Technology Evaluations

December 4th, 2011 at 17:09

Intro

I built a stupid app this weekend. In doing so, I tried out a bunch of technologies that have been around for a while, but are new to me.

They are:

  • Coffeescript
  • jQuery deferred
  • The twitter API
  • JSONP

Here’s my review of each.

Coffeescript

I don’t really like coffescript. I will never be a fan of languages that are whitespace sensitive. But I still use them. I’m willing to overlook the straight-jacket of whitespace sensitivity as long as the laugage is good enough. Now that I think about it, both haml and sass (also used this weekend) are whitespace sensitive, and also compile to a base language before being transmitted. Their benefits are worth it, but they’re not on trial today.

Context

I like the initial idea of the @ operator in Coffeescript. It’s a shorthand for “this.” And you’d better remember that. It can’t be used like you would use it in ruby. I was stuck for longer than I’d like to admit wondering why my assignment to an instance variable wasn’t working in one of my callbacks. Culrpit: @ did not reference my class, but the context that I was currently in. From a javascript perspective, that behavior is obvious. From the object-oriented, ruby-like context that Coffeescript was trying to pretend I’m working in, it was baffling. I had to fall back to the that = this idiom in order to get my callbacks to close over the object I really wanted to operate on.

Documentation

The documentation is pretty abysmal too. You’re lucky if you get more than a couple of examples. The tutorial doesn’t even show how to make multi-line functions! Nor does it demonstrate how to use an in-line function for a function parameter that is not the final parameter. The whitespace-sensitivity can make it a bit confusing.

Only from knowing javascript did I know that I would have to call a co-member function with @ or this. Somehow in their discussion of classes in both the tutorial and the book, they managed to avoid calling a method from another method. I’m not asking for a python style formal grammar documentation, but there’s a lot to be desired here.

Globals

Coffeescript also makes it really hard to write library files. They’ve gone from javascript’s implicit globals to the complete opposite, which is not allowing any globals at all. This is an improvement in many ways, but means you have to fall back to raw javascript or settle with using the window global if you want to actually expose your code to something outside the current file.

I had my code set up with separate responsibilities: a library that interacts with the twitter API, and a UI frontend. These files can’t talk to each other at all without globals. It’s a shame that the architecture of Javascript has forced that behaviour, but coffeescript goes and makes it worse. I had to use the following code to create a global and then drop my class into it:

`TweetMax = {}`
class TweetMax.Twitterer

If it’s not clear, the backticks drop me down to raw javascript. Thankfully I can at least do this, but this is like having to drop down from C to assembly if C didn’t have the extern keyword.

jQuery Deferred

The majority of my interaction with jQuery Deferred objects was just to use the bindings off of ajax actions. However, I did write a few custom ones of my own. It’s a great API, and is probably a pattern that I’ll wonder how I ever lived without.

The one deficiency that I noted, is that you can’t reset the status of a deferred object. Once a deferred object is resolved, it can’t ever be re-resolved. This meant that I had to pull in a proper eventing framework instead of just re-resolving the deferred that I was supplying to the clients of the library. Not a big deal, and for many uses cases, that’s probably a deliberate feature. But for me, it was a deficiency.

Twitter API

The twitter API itself is nice. It’s available in a variety of formats, and is quite sensible about urls, parameterization, and paging.

It all falls down in the service. Throughout the weekend I was constantly plagued with 502s (Service Unavailable). At first, I thought I might be getting rate-limited, since my app does require quite a few sequential requests. After a bit of googling and head-scratching, I discovered that the API service is simply flaky and goes down all the time. 502s aren’t really an exceptional failure with the Twitter API. It means “try again in a few seconds”. When working with the twitter API, you absolutely must write code that anticipates that the servers will be constantly failing to fulfill your requests. Which is okay in theory, but leads us into the next technology…

JSONP

JSONP is a way to get around the cross-domain restriction on XHR requests. This means my clients can make requests directly to the Twitter API without having to filter through my server first. The specific implementation of the format isn’t entirely important, but how it interacts with the browser is. The browser loads the response from a JSONP request the same way it loads any other resource. Basically, to do a JSONP request, you add a script tag to the DOM, the browser fulfills a request, and a function gets called when it all works. What happens when it doesn’t work? Nothing. The only way to figure out that request failed is to set a timeout in Javascript that fires if your function doesn’t get called within an arbitrary time limit. Ouch. So that twitter API that is constantly failing? Doesn’t play very nice with JSONP. Even with the timeout, you don’t get the luxury of knowing what exactly went wrong. So I have to jump through more hoops to tell if I’ve been rate-limited, or if Twitter is just screwing up again.

Conclusion

  • Coffescript: I’ll probably avoid it in the future. You know what you’re signing up for with javascript. Writing “function(” everywhere is annoying for some people, but not for me.
  • jQuery Deferred: A+++++ would use again
  • Twitter API: Hopefully I won’t have any bad ideas that involve the Twitter API again. Of course, my gripes with it aren’t the fundamental parts of the API, just the reliability of delivery. So if they fix that up, I’d be pleased.
  • JSONP: Cool technology, but the inability to detect failures really snuck up on me and derailed this project. Now that I know about that problem, I’ll have to carefully consider what I want to use it for, in the future.

vim, ijkl

January 24th, 2011 at 19:54

My coworkers finally managed to convince me to switch to vim. What a chore. I basically spent an entire weekend customizing someone else’s .vim directory to my tastes, which was mercifully easier than tracking down the plugins and configuring them myself, but it was a frustrating bit of changing my vimrc from within a vim that is not quite configured the way I want it.

It’s a real shame that the vim authors grew up in an era before video games. In my humble opinion ijkl (used in the same way as wasd) is a vastly superior directional scheme to hjkl. It’s directionally intuitive, unlike the linear hjkl, which relies on memorization. It also keeps your index finger on j, where it belongs on the home row. I use h for insert. It’s not as crazy as it sounds. How often do you repeat ‘go left’? Sometimes. How often do you repeat ‘insert’? Never. Because now you’re in insert mode. Stretching to h for repeated go-lefts became uncomfortable, and sometimes I would unconciously move my whole hand to start on h, which would offset my right handed typing and I’d have to find my place on the home row again after moving around.

So far I haven’t run into much trouble. At least vim has the configurability to change this sort of stuff, even if it does take me an entire weekend to get everything sorted out. Thanks go to Deewiant for this comment, which helped me get my bindings consitent.

Here’s the rebindings, for anyone who wants to join my little cult:

noremap i k
noremap I K
noremap <C-w>i <C-w>k
noremap <C-w>I <C-w>K
noremap <C-w><C-i> <C-w><C-k>


noremap j h
noremap J H
noremap <C-w>j <C-w>h
noremap <C-w>J <C-w>H
noremap <C-w><C-j> <C-w><C-h>

noremap k j
noremap K J
noremap <C-w>k <C-w>j
noremap <C-w>K <C-w>J
noremap <C-w><C-k> <C-w><C-k>

noremap h i


Publishers! :(

January 14th, 2011 at 19:08

Availability of “Starship Troopers” by Heinlein:
1. Kindle Store: 0
2. Google search for “starship troopers mobi”: First Link

You lost a sale!


GOMTV Video Ripper

January 8th, 2011 at 12:50

Okay, so it’s done. As done as it’s going to be, anyway. I really can’t be bothered to spend time beautifying a dirty hack of a web scraper. You’ll have to know about ruby and have a gomtv.net login with a season ticket in order for it to work.

Here it is:

https://github.com/Lugghawk/SCScraper

Enjoy.


New Year, New Stuff

January 4th, 2011 at 19:06

I finally got around to some stuff I’ve been meaning to do for a while this weekend/holiday.

  1. With the help of the rest of the l3ibs, l3ib.org and all its corresponding services have been migrated from a dedicated rusty old celeron to a shiny new linode. I like the idea of virtualized machines, since in theory it reduces the impact of a hardware failure, since the virtual machine can be migrated to working hardware with little to no noticeable effect. We’ll see how that turns out.

  2. In addition to the migration of services, I put together a short list of security priorities for the new server. Embarrassingly, the old one wasn’t even running a firewall. The new server feels much safer with the addition of a strict firewall and some rootkit mitigation, but there’s still more to be done. In depth auditing of privilege escalation is possible via sudo, which has an option to launch subprocesses in a virtual terminal and log everything in a way that can be played back like a video. I’ll talk about this and more if I ever get around to setting it up.

  3. As part of the server migration, and part of something I’ve wanted to do for a while now, I’ve migrated to tumblr from wordpress. My wordpress was constantly being hit with comment spam, and I was reluctant to spend time updating a platform I barely ever posted with. Tumblr will let me have a more hands off approach.

    Tumblr’s templating engine is easier to figure out than wordpress’s and I managed to get a working theme ported over in an hour or two. It’s feature barren, but I never intend to use a lot of the features that tumblr provides anyway.

    I like tumblr’s custom domain solution. It was easy to set up and works nicely.

  4. With a new season of GOMTV starting up again, I took it upon myself to see if I could get my video scraper working. The goal is to be able to grab all of the videos without much human intervention. It was possible to get all of the videos before by just taking them out of Flash’s temp directory, but it was a cumbersome manual process, and prone to spoilers. If I can get this to work, it’ll provide a technique for archival, as well as a way to much more easily stream the content to my PS3.

    Turns out GOM has modified their site between seasons again, which meant that about half of my previous reverse engineering work had to be redone. Fortunately they didn’t change the fundamental way of authenticating that you have a season ticket and downloading the video. HTML scraping just had to be done in a different way, and I’m guessing this problem will repeat itself because will continue as GOM improves their site as time progresses.

    I sort of have a script working. It can fetch some videos, but I’m running into frustrating-to-debug corner cases.

    I will post about progress as it happens.

mediastreamer transcoding support

May 24th, 2010 at 15:50

I’ve recently been using mediastreamer to stream my music to work. The actual audio playback portion of mediastreamer relies on either flash or the HTML5 

Anyway, about half my collection is in FLAC. Even if the endpoint did support FLAC playback, it would be too large to be practical for all-day-streaming. Since I didn’t want to go to the bother of reencoding my entire collection just so I could stream it over the internet, I sat down this weekend and started hacking transcoding support into mediastreamer.

The tag reading library used by mediastreamer already supported FLAC, so adding FLAC files to the database was as simple as updating the glob that searched for files. My approach to transcoding was to use commandline tools to decode and reencode the file in question, and then pipe that into the webserver for streaming. It turns out that everyone’s implementation is broken in some way unless I specify a Content-length header. As far as Flash is concerned, files hosted without a Content-length never end, meaning the playlist never advances. Chrome’s native

There’s two ways I can think of to know the file-size, so that I can set the Content-length header in HTTP:

  1. Transcode the entire file before streaming, and just look

  2. Use a deterministic method of encoding, so that the size of the output file can be estimated by looking at the length of the input file


I tried method 1, but I was not satisfied with the several second pauses between files. Since I plan on deploying this solution to a computer much slower than my development machine, the pauses between files would be even longer, and unacceptable.

Method 2 is currently in development. Deterministic output means that VBR is right out, so I’m stuck with encoding to CBR mp3. I’m estimating the Content-length by multiplying the length of the song in milliseconds by (bitrate / 1000). This is close enough, but somehow results in a length several kbytes longer than the output from lame. Interestingly, this doesn’t seem to affect Flash; the Content-length doesn’t need to be right, it just needs to be close. How frustrating. Still, it would be nice to know how to accurately predict the output of lame. It’s unsettling to be setting incorrect Content-lengths.

I’m going to look into submitting bug reports to webkit for their poor <audio> support. Or maybe not. It’s possible that Sinatra is just incorrectly responding to Range requests, which webkit seems to like - but range is probably a dangerous proposition for a file that’s being dynamically generated, so I’m not entirely sure whose fault it is. No other browsers use Range when they make requests for their <audio> tags, as far as I can tell. Unfortunately, I’ll probably have to build a webserver that hosts both vorbis and mp3, without Content-length headers, to test this across a wide range of browsers.


BFBC2ConfigTool Alpha 3

March 24th, 2010 at 21:39

Download

Browse Source

Another bugfix release. Looks like I forgot to set ConceptRoll for turrets (because apparently you want to roll vehicles). Not being able to move turrets left and right should be fixed. If your config files are in a non-working state, simply open the program and hit save for a fix.


BFBC2ConfigTool Alpha 2

March 24th, 2010 at 14:33

NOTICE: Alpha 2 is bugged. Please get Alpha 3. Download Browse Source Alpha 2 is out already, with fixes:

  • Completely forgot to modify relevant parts of GameSettings.ini in Alpha 1, now fixed
  • Program now exits gracefully when BFBC2 directory not found, instead of crashing
  • Warning message actually says what it should

BFBC2ConfigTool Alpha Release 1

March 24th, 2010 at 04:37

NOTICE: Alpha 1 is bugged (big surprise). Please get Alpha 3.

Download Alpha 1

Browse Source

This is the first release of the BFBC2ConfigTool. I’ve hacked up a quick alpha version that should painlessly deactivate mouse smoothing, and allow people to fiddle with their sensitivities. There’s also an option to make the Russians in BFBC2 speak in English, since apparently some people were encountering problems with that.

This initial alpha release is targeted mainly at reddit users. If all goes well, I’ll post about this on the EA forums.

This is alpha software. It will probably break. Use at your own risk. There is currently no input validation. I take responsibility for nothing. Please report bugs so I can fix them.

To use, simply run the provided exe. You need .NET 2.0.


Proof of concept BFBC2/HTTP Redirector

March 18th, 2010 at 20:47

As noted by a reddit post, reddit doesn’t accept bfbc2:// style links. It’s probably going to be a fairly common problem. I wrote a proof of concept script that just does a simple 302 redirect from http to bfbc2. The base URI is http://fitzsimmons.ca/bfbc2/[server string here]. You can enter a server string raw, or URLified (with bfbc2:// on the front) and the webserver will automatically redirect you to a URI that the handler can pick up.

Here’s a couple examples:

http://fitzsimmons.ca/bfbc2/2503473115,3fc5640a-7dbb-415f-9e45-ba6cec0562dc,A Bacon Server

http://fitzsimmons.ca/bfbc2/bfbc2://3363010643,b652b484-4188-42ea-8885-50fc4991af5b,Reddit%20Unofficial%20Gaming%20Community-%20Chicago

This should allow you to link from places that only allow http style URIs. If this takes off at all, I’ll write a some info about what’s happening on the redirect page, for people that don’t have the handler set up.


1 2 3 4 Next