Find people with similar interests

If You watch this blog using web browser You may have noticed new widget in sidebar. Probably for You looks like that:

When not logged

What is this?

When You click on it You will be taken to FriendsFeedMe application to login or create account and upload OPML. For people logged to FFM (and with OPML file uploaded), widget looks like this:

When not logged

You see? When You upload OPML we can try to calculate how much Your and blog owner interests interacts. So when You find somewhere in net blog with this widget You will know how many Yours and site owner OPMLs have in common.

When You look at own widget You have button to upload new OPML file.

Widget is first feature on FFM which is not based on Your direct connections in Facebooks social network – You could get info about any user who uses FFM and puts widget on public site. There will be more such features in future!

Do You want such widget?

Go to FFM (login or create account) and click on options tab. Now copy widget code and paste to Your webpage. Widget has size 180×95 pixels. Have fun!

Stable Google Maps API

Stable – read slow changing. Yesterday Google has announced new version of its Google Maps API. This time it is not new feature full release, it is promise to keep API version not updated every two weeks.

I mean – it is good that Google offer a lot new features, but from developer point of view it is not good thing in application maintenance terms. New features often have some side effects or just API changes and applications even not using new features has to be adjusted to this new release. Or at least tested ;)))

For me it additional overhead, since I do develop RNS, but currently is not my main focus. Stable GM API version means less maintenance work for me, and more time to think and implement new features (not only in RNS but mainly FriendsFeedMe)

DRb and security

FriendsFeedMe application is build around RSS feeds and relations between people. As result we need to process a lot of OPML files. My first approach to this task, was build web frontend (Rails powered application) and some library to process data uploaded via frontend, and display results via web.

Processing was done in fixed intervals (script called from cron). Why that way? Since it was simplest approach which allowed to automate whole process. But it has several drawbacks: user have to wait before he will see results, it is hard to illustrate task progress, so I had to rewrite this part in some point in time. The time has come.

Natural was to use DRb (Distributed Ruby), build independent server to process data taken from DB, and from Rails application notice that processing is needed (new OPML uploaded). Using DRb is pretty easy and I don’t want to talk about how to use it this time.

To DRb server You can connect via TCP or UNIX sockets. Since our setup is currently on one host I prefer socket version – opening another TCP port in listening state without real need is something I would avoid.

You can imagine my surprise, when after I have started DRb server connected to socket I discovered this:

$ netstat -an | grep LISTE
tcp4       0      0  *.61841                *.*                    LISTEN
[cut]

$ telnet localhost 61841
Trying ::1...
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
[ENTER]
[ENTER]
:DRb::DRbConnError:bt[ "5/usr/local/lib/ruby/1.8/drb/drb.rb:573:in
`load'"=/usr/local/lib/ruby/1.8/drb/drb.rb:612:in
`recv_request'"=/usr/local/lib/ruby/1.8/drb/drb.rb:911:in
`recv_request'"B/usr/local/lib/ruby/1.8/drb/drb.rb:1530:in
`init_with_client'"?/usr/local/lib/ruby/1.8/drb/drb.rb:1542:in
`setup_message'"9/usr/local/lib/ruby/1.8/drb/drb.rb:1494:in
`perform'";/usr/local/lib/ruby/1.8/drb/drb.rb:1589:in
`main_loop'"6/usr/local/lib/ruby/1.8/drb/drb.rb:1585:in
`loop'";/usr/local/lib/ruby/1.8/drb/drb.rb:1585:in
`main_loop'"7/usr/local/lib/ruby/1.8/drb/drb.rb:1581:in
`start'";/usr/local/lib/ruby/1.8/drb/drb.rb:1581:in
`main_loop'"5/usr/local/lib/ruby/1.8/drb/drb.rb:1430:in
`run'"7/usr/local/lib/ruby/1.8/drb/drb.rb:1427:in
`start'"5/usr/local/lib/ruby/1.8/drb/drb.rb:1427:in
`run'"</usr/local/lib/ruby/1.8/drb/drb.rb:1347:in
`initialize'"5/usr/local/lib/ruby/1.8/drb/drb.rb:1627:in
`new'"?/usr/local/lib/ruby/1.8/drb/drb.rb:1627:in
`start_service'"*./script/../config/../config/ffm.rb:6"^/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`gem_original_require'"Q/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'"3./script/../config/../config/environment.rb:18"^/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:
`gem_original_require'"Q/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'"L/usr/local/lib/ruby/gems/1.8/gems/rails-1.2.3/lib/commands/runner.rb:39"^/usr/local/lib/ruby/site_ruby/1.8/rubyg
`gem_original_require'"Q/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in
`require'"./script/runner:3:      mesg" too large packet
1935959667Connection closed by foreign host.


I’m not sure whether it is exploitable by any means, so I started digging around this topic. It looks like every script which executes DRb.start_service (even setup as client only!) opens new TCP server on some random, high port.

So there is solution for this – Ruby’s ACL – Access Control Lists. Of course it is very wise to block unwanted ports on network level, but not always it is easy to accomplish due to some restrictions casued by… well, human factor ;-) In such case You can block access to this port using mentioned ACLs. Example will be the best way to show it. This is content of my ~/.irbrc when I did a lot test to DRb enabled processing.

require 'drb'
require 'drb/acl'
require 'pp'

acl = ACL.new( %w[deny all] )
DRb.install_acl(acl)
DRb.start_service

Since irb works only as DRb client, I don’t need any TCP connections, so I can disable all of thems (deny all). This code I also use in my server since it is one host setup with connection via UNIX socket (URI to connect to DRb server looks like "drbunix://tmp/socketName"). It is possible to use some more sophisticated entries:

acl = ACL.new( %w[allow 127.0.0.1/32
                allow 87.0.0.0/8
                deny all] )

Will allow connect to DRb server via TCP from localhost (127.0.0.1), all host with IP addres with 87 in first octect and deny all other folks.

All examples were tested with ruby 1.8.6 (2007-03-13 patchlevel 0) [i386-freebsd6]

Google Maps API as debugger tool

AJAX applications can get hard to debug. Recently developing FriendsFeedMe I got to the point, where I had three AJAX calls called in sequence (by onScuccess callback). More, this could happen in multiple instances in parallel. Well… it was messy, but was just working, so I did not clean up it without need (don’t fix if it is not broken!).

But time has come, when, after code update something started to be wrong. And bug was happening only when AJAX sequences were called more than two at one time. Debugging such a complicated (well I should just say – messy) setup it is real nightmare. Standard tools, like Firebug are not enough, since classic breakpoints and step by step approach fails, when bug is visible only in dynamic environment, when a lot is happening in short time.

So what left out? Clean up code? Right, but when it is not easy task, You may try other approach. Logging. You need some good debug output, and dump application state to this channel. And here comes Google Maps API with help. One of its components is GLog namespace, which provides nice logger.

Just go to Google Maps API website, register API key for Your app, and include Google Maps API library. Now You can use GLog.write to write messages to logger. When first message will show up, GM API will create new div on current page which will contain all messages sent using GLog namespace. Logger provides timestamps, div with logger has scrollbar and is movable. For HTML formated output You can use writeHtml and for URLs writeUrl. Equipped with such tool You can approach debugging some asynchronous JavaScript calls.

I did just code cleanup and use simple solution instead of debugging mess I had, but if You insist…

RNS now comes with labels

Last night I have pushed new RNS version. This time it is rather significant update.

Now every point on route can be labeled with some text and use some additional icon. Currently there are two types provided – information and warning sign. You can see example on this route. Click on icon to see label.

This update I wrote some time ago, I had make only few last changes. I took so long only because of my new project FriendsFeedMe. Despite of this I still have plans related to RNS – like add widget capabilities (embedding maps created with RNS in other sites) or general layout redesign. Now, after few weeks cooperation with Losamorales, which is responsible for FFM look I can not stand ugly RNS layout anymore :)

So expect more new releases in future!