Monday, March 31, 2014

Getting websocket-rails up and running on Heroku

I wanted to document my endeavors to get websocket-rails up and running on Heroku. In my case, I'll be adding Redis to the mix, as I'm trigger server-side events from a worker process that is running delayed_job tasks. Thus, in a multi-process environment, Redis has to be used to communicate from the worker process to the Rails process (which actually maintains the web socket infrastructure). My experiences with setting this all up were actually quite pleasant and things just worked without many issues. The documentation for websocket-rails could benefit from elaborating some non-development environment scenarios, but that's a very minor gripe.

Step 1: Get the solution running in development

Pretty straight-forward. You have to get everything working in your development environment. Nothing earth shattering here, but if you plan on triggering server-side events to your JavaScript clients from something like delayed_job, you will need to use Redis. I'm using OS X Mavericks here, so I install tools through Homebrew. Here's how I got Redis up and running in my environment:
  1. Install via Homebrew: brew install redis
  2. Start up Redis from the command line: redis-server /usr/local/etc/redis.conf
If you need to monitor Redis, use the redis-cli: redis-cli monitor Now that we have Redis up and running, get websocket-rails integrated into your application. I won't belabor how to do that--the documentation does a good job of detailing how. I use a channel to communicate from the client-side and the server-side. Another thing to note is that for anything I do on the client that I want an event for coming from the server, I use a correlation ID from the client-side that I can keep track of on the client-side, so when an event from the server-side is received, I can determine whether I'm interested in it because it contains the original correlation ID. Read more here about the correlation ID design pattern.

Step 2: Get the solution running on Heroku

Now that everything works in development, I needed to get the solution out to Heroku.
  1. If you previously installed SSL, you will have to disable it before enabling websockets support. Remove the certificates: heroku certs:remove, then remove SSL support through the Dashboard.
  2. Enable websockets support: heroku labs:enable websockets
  3. Add a Redis provider Heroku addon to the app if you haven't done that already. Note the Redis connection information.
  4. Update the websocket_rails.rb initializer with the Redis connection information. I had to add some conditional logic to determine which environment I was deployed in. Also import here is that host and port won't typically be enough to connect to a Redis add-on. You'll definitely need a password and probably a username. Those can be passed through the redis options in this initializer. Currently my websocket_rails initializer has some code in it like this:
    
        if ENV["RAILS_ENV"] == 'production'
            config.redis_options = {
                username: 'rediscloud',
                password: 'UHDDBHD&*#$DFkkdfha',
                host: 'pub-redis-88885.us-east-1-3.3.ec2.redisdomecity.com',
                port: '15204'
            }
        else
            config.redis_options = {
                host: 'localhost',
                port: '6379'
            }
        end
    
    
    This will invariably change so I can differentiate between staging and production, but you get the point.
Doing all this I was able to get the websocket-rails stuff to work and have not had any issues with it, even with dynes spinning up and down.

Tuesday, March 18, 2014

Installing pillow on OS X Mavericks with Xcode 5.1

I've been doing some Python and Google App Engine development lately and I hit an issue with clang throwing an error like the following....
cc -fno-strict-aliasing -fno-common -dynamic -g -Os -pipe -fno-common -fno-strict-aliasing -fwrapv -mno-fused-madd -DENABLE_DTRACE -DMACOSX -DNDEBUG -Wall -Wstrict-prototypes -Wshorten-64-to-32 -DNDEBUG -g -fwrapv -Os -Wall -Wstrict-prototypes -DENABLE_DTRACE -pipe -arch x86_64 -DHAVE_LIBJPEG -DHAVE_LIBZ -I/System/Library/Frameworks/Tcl.framework/Headers -I/System/Library/Frameworks/Tk.framework/Headers -I/usr/local/include/freetype2 -IlibImaging -I/System/Library/Frameworks/Python.framework/Versions/2.7/include -I/usr/local/include -I/usr/include -I/System/Library/Frameworks/Python.framework/Versions/2.7/include/python2.7 -c _imaging.c -o build/temp.macosx-10.9-intel-2.7/_imaging.o

clang: error: unknown argument: '-mno-fused-madd' [-Wunused-command-line-argument-hard-error-in-future]

clang: note: this will be a hard error (cannot be downgraded to a warning) in the future

error: command 'cc' failed with exit status 1

The following discussion helped: https://stackoverflow.com/questions/22334776/installing-pillow-pil-on-mavericks I've had more issues with the March 2014 version of the Command Line Tools for Mavericks. Grrrr.

Tuesday, February 11, 2014

Copy as HTML plugin in RubyMine

Just a quick note: the Copy as HTML plugin does not show up in the RubyMine 6 plugins listing. But if you download it from here, and install it from disk through the Plugins preferences page, it will work flawlessly in RubyMine. Not sure why it does get listed, but it's a great plugin nonetheless.

Using Teacup to style individual UIView components

I've been doing a bunch of RubyMotion development lately and I'm continually amazed at the power of this framework. One of the many great tools available to RubyMotion developers is Teacup, a UI view layout and styling domain-specific library (DSL). I think DSLs are one of the big advantages that RubyMotion has over traditional native iOS development using Objective-C and Xcode. More information on Teacup here. There's tons of documentation around using Teacup with UIViewControllers, but scant documentation on using Teacup with custom UIView components. There are times that you cannot style a UIView or subclass when the view is initially rendered. Examples include table cells and table headers. Well, don't fear, because you can always mix-in the Teacup layout behavior into any old Ruby class and get that functionality. Below is a table view header helper class that creates new UIView objects with a UILabel subview. Notice how I mix in the Teacup::Layout behavior into the helper and then I have access to all the Teacup stylesheet and layout functionality.

 1 class TableViewHeaderHelper
 2     include Teacup::Layout
 3 
 4     stylesheet :table_view_header
 5 
 6     def create(frame, title)
 7         view = UIView.alloc.initWithFrame(frame)
 8         view.stylename = :root
 9         layout(view) do
10             label = subview(UILabel, :label)
11             label.text = title
12         end
13         view
14     end
15 
16 end

In this above example, the factory method takes a frame and a title for the header. I create the root UIView and then pass that to the Teacup layout to do the rest of the composite magic. Since the title is dynamic, I get a reference to the created UILabel and set the text of the label to the title string passed into the factory method.

Next up is the Teacup stylesheet. This sits in app/styles/styles.rb in my RubyMotion application. I defined a couple of global UIColor objects and then define the table_view_header style for use in the TableViewHeaderHelper class previously shown. The rest of this is standard Teacup functionality, so I won't repeat what they have already documented.

 1 sectionBackgroundColor = UIColor.colorWithRed(221/255.0, 
 2                                               green: 238/255.0, 
 3                                               blue: 249/255.0, 
 4                                               alpha: 1.0)
 5 headerTextColor = UIColor.colorWithRed(50/255.0, 
 6                                        green: 50/255.0, 
 7                                        blue: 50/255.0, 
 8                                        alpha: 1.0)
 9 
10 Teacup::Stylesheet.new :table_view_header do
11 
12     style :root,
13           backgroundColor: sectionBackgroundColor
14 
15     style :label,
16           top: 1, 
17           left: 15, 
18           width: 500, 
19           height: 40,
20           font: :bold.uifont(20),
21           textColor: headerTextColor
22 end

Finally are the UITableViewDelegate protocol methods that I implemented to get a custom header for my UITableView. Note that the frame height used for constructing the UIView in the TableViewHeaderHelper is ignored, and the UITableViewDelegate heightForHeaderInSection:section method is used to determine the header height instead. Kind of strange, but it works.

 1     def tableView(tableView, viewForHeaderInSection: section)
 2         frame = CGRectMake(0, 0, tableView.frame.size.width, 1)
 3         title = "#{@league.name}: My Stations by date"
 4         TableViewHeaderHelper.new.create(frame,
 5                                          title)
 6     end
 7 
 8     def tableView(tableView, heightForHeaderInSection:section)
 9         50
10     end

Thursday, January 02, 2014

Google App Engine\Python: Using the task queue with a reverse proxy or SSH tunnel

This is more a note for myself. When using forward, a SSH tunnel Ruby gem from the folks at forwardhq.com, Google App Engine\Python devserver will barf trying to resolve the Host header when dispatching tasks on the task queue. In my case, my tunnel hostname was coming through in the Host header, causing the KeyError in _port_registry.get(port) invocation.

dispatcher.py


  def _resolve_target(self, hostname, path):
    if self._port == 80:
      default_address = self.host
    else:
      default_address = '%s:%s' % (self.host, self._port)
    if not hostname or hostname == default_address:
      return self._module_for_request(path), None

    default_address_offset = hostname.find(default_address)
    if default_address_offset > 0:
      prefix = hostname[:default_address_offset - 1]
      # The prefix should be 'module', but might be 'instance.version.module',
      # 'version.module', or 'instance.module'. These alternatives work in
      # production, but devappserver2 doesn't support running multiple versions
      # of the same module. All we can really do is route to the default
      # version of the specified module.
      if '.' in prefix:
        logging.warning('Ignoring instance/version in %s; multiple versions '
                        'are not supported in devappserver.', prefix)
      module_name = prefix.split('.')[-1]
      return self._get_module_with_soft_routing(module_name, None), None

    else:
      if ':' in hostname:
        port = int(hostname.split(':', 1)[1])
      else:
        port = 80
      try:
        _module, inst = self._port_registry.get(port)
      except KeyError:
        raise request_info.ModuleDoesNotExistError(hostname)
        _module, inst = None, None
    if not _module:
      _module = self._module_for_request(path)
    return _module, inst

The line in red is the line that is barfing. Comment out the raise error line and set _module and inst to None, allowing execution to continue and the next line will test if _module hasn't been set and will go ahead and resolve it. Found the temporary fix from https://github.com/dylanvee/homebrew-gae_sdk. Hopefully this is something the GAE people can fix in upcoming versions of GAE\Python SDK.

Friday, December 20, 2013

Rubymotion: Controlling Info.plist generation with environment variables

I've been doing a fair amount of Rubymotion development these days and one trick that I'm using in my local development is to control the generation of the Info.plist via environment variables and some Ruby coding in the Rakefile. I can't stop raving about the excellent tools and development cadence that Rubymotion affords the iOS developer. I really like that I'm working out of Rubymine and not Xcode and using standard Ruby tools like rake and Bundler.

Like I said, using rake, you have the opportunity to change your Info.plist because it's generated through the rake process. I have a login view that needs a username and password entered into the text fields. I've rigged it up that these are prepopulated when working in dev, using environment variables and adding some logic to my Rakefile and the view controller. First up are the environment variables:

export DEV_MODE="true"
export DEV_USERNAME="chris.bartling@mycompany.net"
export DEV_PASSWORD="fahj2734hfjg86776dg$48df676"

Nothing earth shattering here. Normal environment variable assignments. Next up is the Rakefile changes:

Motion::Project::App.setup do |app|
    
	...    

    if ENV['DEV_MODE']
        puts '==========================================='
        puts '===> Using DEV_MODE Info.plist values <===='
        puts '==========================================='

        app.info_plist['DEV_USERNAME'] = ENV['DEV_USERNAME']
        app.info_plist['DEV_PASSWORD'] = ENV['DEV_PASSWORD']
    end

    app.pods do
        ....
    end
end

Again, pretty simple Ruby stuff here. If the DEV_HOME environment variable is set, add the username and password to the Info.plist during generation. Now, in your app, you can reference these values in your viewDidLoad method of your view controller, prepopulating the UI elements in your views:

dev_username = NSBundle.mainBundle.objectForInfoDictionaryKey('DEV_USERNAME')
dev_password = NSBundle.mainBundle.objectForInfoDictionaryKey('DEV_PASSWORD')
@email_field.text = dev_username || ''
@password_field.text = dev_password || ''

I probably sound like a broken record, but if you haven't used Rubymotion, definitely give it a try. Much different developer experience using Rubymotion tools vs. Apple's Xcode tooling.

Retrieving logs from your deployed Google App Engine Java application

If you need to see your application logs from your deployed Google App Engine (GAE) Java application, you can use the GAE appcfg.sh tool to do so. Issue the following command from your GAE app directory:

appcfg.sh --num_days=0 --severity=0 request_logs ./web ./logs/gae.log

where:

--num_days=0 will retrieve all of the logs available,
--severity=0 will retrieve DEBUG and above log levels,
./web is where the ./WEB-INF/appengine-web.xml descriptor file can be found, and
./logs/gae.log is the local log file to write records to.

There are other options available for this command. Execute appcfg.sh help request_logs to see more information on the options available for request logs command. This will dump all of your logs and they will not be truncated like they are in the Logs view of the GAE administration application.

Thursday, December 19, 2013

CoffeeScript Application Development by Ian Young

I had the opportunity to read CoffeeScript Application Development by Ian Young recently and thought I would put together a book review.

The author does a nice job describing why parentheses are required for executing CoffeeScript no-argument functions. This is an idiom that I have seen many developers trip over when first coming to CoffeeScript. CoffeeScript preserves JavaScript’s view of functions as first-class citizens. Parentheses are optional except when necessary to avoid ambiguity.

The author gives some nice examples of loop comprehensions, one of the snazzier features of CoffeeScript. Loop comprehensions come from Python and they make for a more readable way to iterate a list and selectively act on list elements which meet a certain criteria. I’m always looking for more examples of loop comprehensions in CoffeeScript and this book has some nice examples.

The CoffeeScript switch statement is explained thoroughly. This is a handy flow-control statement that works really well in its incarnation in CoffeeScript. There are numerous examples in the book where different usage scenarios are demonstrated. Very handy and welcomed.

I found the author’s treatment of classes and inheritance in CoffeeScript to be a nice, gentle introduction. The examples that are given in the book work well and the explanations that accompany the examples are clear and concise. It would have been nice to get an explanation of the boilerplate code that CoffeeScript generates for you when defining a class, but I guess that’s considered part of the magic of CoffeeScript. It isn’t until the discussion on inheritance that the author starts to poke his head under the hood to investigate the generated JavaScript. The inheritance discussion is extremely valuable and a big plus for this book. If you get this book for anything, it’s for this discussion. CoffeeScript is doing a whole bunch of interesting stuff when creating classes and implementing inheritance, and this is one of the first times that I have seen the generated JavaScript described line by line.

In typical fashion, the author introduces the fat arrow syntax in a gentle manner, clearly explaining the reasoning for such a feature. The author then gives a very good explanation why you should not overuse the fat arrow syntax in your CoffeeScript (hint, it’s due to memory usage). He also includes a very succinct definition and example around memoization in CoffeeScript. This is a feature that I have not had much exposure to, so it was great to see it described and used in an example.

IcedCoffeeScript is introduced in the chapter on Going Asynchronous. I have not used IcedCoffeeScript, so that was an interesting exploration into an extension to CoffeeScript for managing asynchronous invocations. Looks interesting.

The topic of debugging CoffeeScript is broached. This is an interesting subject, as I have seen a few developers really get frustrated with the mapping of generated JavaScript back to the original CoffeeScript. Luckily the author introduces source maps, which does this work for us. The author shows us how to set this feature up in Firefox and Chrome developer tools. Your mileage will vary on this feature, but it is an interesting tool for easing the inertia of moving to CoffeeScript. This discussion comes with a lot of screenshots that help you understand how the source maps feature can be used in the developer tools.

Overall I really liked this book and it’s a worthy addition to my other documentation on CoffeeScript. Link to the book

Tuesday, November 12, 2013

Debugging Before and After hooks in Cucumber

Had a heck of time trying to figure out why all my Cucumber steps were completing successfully, but my Cucumber scenario would fail. Seems that I had an issue with the web app that I was testing which would hit a REST endpoint asynchronously during the Cucumber scenario, causing an error. Cucumber seems to eat this normally, but running with the command line option of --format pretty dumps the backtrace of the exception. Blogging about this so I don't forget about it. Reference: https://groups.google.com/forum/#!topic/cukes/WTJDVWGQkTM