Dev Env acting up when trying to do bulk operations
(What a title…) I was pulling my hair out over the last two days when I was implementing bulk operations in a project of mine.
In this case, the list of operations to do in bulk is compiled in the browser, and then the single requests are sent one by one to the server as single AJAX requests. (Think “mark this as read” functionality.)
My problem was that the first and second call in the bulk list usually went through well, but the rest of the calls just ran against a wall since all of a sudden Rails had problems finding the either logged in user or was missing certain methods and/or attributes. Highly annoying as well as completely erratic, as I was sure my code was okay in the first place.
When trying the same operations on a one-by-one basis, all was good. No issues whatsoever.
So while trying to figure out what the fuck was going on, I’ve played around with different ways to get the current user, checking for the availability of its methods and so on, all to no avail.
At one point I’ve disabled the protect_from_forgery call, and one or two different errors started to appear:
A copy of ApplicationController has been removed from the module tree but is still active
That was new. So I’ve started digging around for an answer, and found it in an old Ruby Forum thread.
Turns out that Rails’ development mode was the culprit, as the app’s code is reloaded on every request; so when a lot of concurrent calls are made, the code might reload slower than the calls are coming in and hijinks ensues.
The overly simple solution to this problem? In /config/environments/development.rb, I just set config.cache_classes to true, meaning the code isn’t reloaded all the time — and as it turns out, my code runs just fine after all! Happy happy joy joy.
The downside is that I’ll have to restart my dev server every time I make a code change, but in this particular case, that’s not a big deal.
xss_terminate vs Serialized Data
When using serialized data fields in an ActiveRecord model, xss_terminate will cause problems when saving as it will try to use String methods when it’s actually dealing with a hash or an array. This can be avoided by telling the plugin to ignore these fields:
A Shorter `collect`
Instead of writing (for example)
Customers.find(:all).collect { |c| c.email }
you can also write
Customers.find(:all).collect(&:email)
I didn’t know that. Nice!
god gotchas
I’ve spent a couple of hours today pulling my hair out while trying to get one of my background job scripts to work with god, the “easy to configure, easy to extend monitoring framework written in Ruby”.
Well, it took a while to make it work, tho. Yes, god is cool and simple and gets the job done. But there are some things that cost me hours and which I found out only by reading the source code.
So, I just want to quickly jot down some gotchas before I forget them again, running the risk of falling into the same traps again in the future.
My script used the constant
LOGto keep myLoggerinstance. Logging worked fine when I ran the script by itself, yet when god took over, it didn’t anymore. Actually, the script died rather quickly. As there was no logging at all going on, and all STDOUT output was suppressed, I came rather close to losing it. Turns out god itself is declaring aLOGconstant of its own, which was done before my script had the chance, so when it attempted to initialize it, it would actually try to re-declare an existing constant, and we all know how well that works. ;)Once that was done, my script was logging just fine, but it didn’t produce any output whatsoever. Raah! Teeth were gnashed… there was definitely teeth gnashing going on. Even telling “my”
Logger(the one inside my script) to write to a file didn’t produce anything. That was a fun hour, really. The reason for this behaviour: god is closing all open file descriptors when it sets up monitoring a script. Which included my script. Awesome! On the upside, it meant I could get rid of the part of my code dealing with different logger behaviours. Meaning less LOC! It doesn’t get any more agile than that, folks.In case you actually want to capture anything your original script is sending to STDOUT, there’s the not-really-documented
God::Watch#log. Set it inside yourGod.watchblock to specify a log file. (See example below.)If you need to set ENV variables,
God::Watch#envis your friend. Accepts a hash with arbitrary key/value pairs. For example, I declare a fewGod.watchblocks, one for each value of an array (think “worker 1 to 5”), and I useGod::Watch#envto pass the current value to the worker script. Works well.When you do a
sudo god stop <watch>, make sure to give it a few moments before runningsudo god start <watch>again, or you might end up with orphaned unmonitored scripts running rampant in the background.Running
sudo god logwithout any further arguments will tell you that “You must specify a Task or Group name”. That’s actually a lie, as it only accepts task names. (A group is a number of related tasks. A task is a single monitoring watch.)
So, yeah.
Don’t get me wrong, please: It might not look like it, but once I had figured it all out, I’ve decided I actually like god. I like the feature set, it’s really easy to set up, and it works. I’m happy it exists.
How Closures Behave In Ruby
this is totally gonna work… » Blog Archive » Ruby Threads Suck…Just Not The Way You Think They Do
I didn’t run into this trap myself (yet), but it’s worth remembering nonetheless.
Validating email addresses more thoroughly
Email Veracity, “A straight-forward Ruby library for checking the real-world validity of email addresses”, rocks. I’ve installed the gem, added it to my environment.rb…
…and now I can check the email addresses more thoroughly.
Email Veracity checks address domains for MX and/or A records, offers whitelists/blacklists etc. It’s neat, I like it.
Kernel#retryable 
Kernel#retryable by Cheah Chu Yeow, which I’ve slightly enhanced and rebuilt as gem as a little Munich Hackday project. Runs a code block, and retries it when an exception occurs. It’s great when working with flakey webservices (for example).
Initializing gotcha
I came across an interesting behaviour today. The #initialize method of a class contained some faulty code towards the bottom, but strangely enough the code that came before was …forgotten. Apparently the raised exception made Ruby ignore the instance variables that came before. Observe:
Took me a while to understand what’s going on. It makes sense, though — because of the error, the class won’t be initialized, because the method call doesn’t return anything internally. However, I was expecting the code to be executed up to point where the error occured; i.e. I was surprised to see mc ending up being nil.
