Arthur Chang

How do you define real-time?

How exactly do you define "real-time"?

Currently a lot of companies are coming out with a real-time label on some aspect of their service. The trend seems to be:

  1. Content they serve is now automatically updated without needing viewers to manually reload.
  2. Content is updated sooner and faster
  3. Slap a chat on it, call it real time. 
  4. Put some twitter, facebook, openid, what have you and call it social real-time.

I see real-time as things happening at the exact moment, which is updated a bit faster than 10 seconds. But you are real-time with what? The server? Everyone you follow on Twitter? The key is to have someone on the other side to be real time with you. That is what is interesting.

To be Real-time there are some particularly important points:

  1. Content you're interested in that people provide. (twitter.com updates, friendfeed, digg stories)
  2. Action sharing, such as screen sharing or browse sharing. (webex solutions, browseology.com)
  3. Information generated from a source that is time sensitive, not necessarily from the mass of people, but from a single entity. (big events like sporting events)

What's your definition?

Relay for Life - Willow Glen, CA

The best way to spend your birthday is to volunteer for a good cause.  I made the decision to go down to Willow Glen, CA to help out and photograph the Relay for Life.  Relay for Life is a 24 hour event, organized and run by volunteers and staff of American Cancer Society, to honor and remember cancer survivors, patients, and those who have passed.  The event is the largest fundraising event the American Cancer Society puts on every year, and this year especially needs every bit of help possible.  It is touching to attend and be part of these events, and I encourage everyone to take some time out of their busy lives to volunteer some time and effort to help good causes such as the Relay for Life.  Find more information here.

I took some photos at the event, I hope these inspire and motivate everyone to be more involved and seek to be more aware of cancer:


American Cancer Society







together







untitled






untitled





view







remember and hope







untitled




Luminaria






Holding Light






HOPE

OASES Benefit Dinner 2009

I had the honor of attending the OASES Benefit Dinner of 2009 in Oakland, CA last Thursday.  It was a fantastic program, and to top it off, the shots I took a few weeks prior were displayed in 35 x 24" sizes all around the entire venue!  It was fantastic to know that the pictures were good representations of the program that everyone was happy to show.  I brought my camera with me to the dinner / event of course, and took a few shots:




OASES Benefit Dinner






OASES take a bow







polka dot




capoera

Humanized Messages for Prototype

Click here to download:
kineticmsg.js (3 KB)

Humanized Messages for Prototype

Download

I ported this cool jQuery javascript library called Humanized Messages over to Prototype and Scriptaculous.  For those unfortunate enough to be stuck with Prototype and can't use all of the great slick jQuery libraries, here's one to add to the Prototype list.  Attached you'll find the latest javascript and css file that you'll need to add to your pages.  Remember to include the prototype and scriptaculous libraries as well.

To see a demo, see the original Humanized Messages demo page.

Tested with Prototype v1.6.0 and Scriptaculous v1.8.2 on Firefox and Safari.

Description: this creates a cool popup message when clicking links, and adds messages to a message log.  Really grabs your attention smoothly.  Make sure you're including the kineticmsg.js and kineticmsg.css files from the google code page.

    New in 1.1
    * Prototype v1.6.0 support
    * Scriptaculous v1.8.2 support
    * Extra small bump at end of vertical shake
    * Removed race condition of trying to bounce tab while already bouncing

... I miss the beach

When will summer finally come and stick around?  I totally miss the beach.  Three weeks ago or so when I was there, it really felt great.  I can sit in the sun all day, every day.  Being outside in the warmth is one of the greatest feelings in the world.  I miss it so much I went and posted a few more pictures from the beach:


a guy, girl, water, and flickr pro




surface





future




forward




growing up

Tagged  //   photography  

Monitor memcached with Monit and alert with Gmail

I setup monit on a production slice running Ubuntu to monitor memcached using the directions on Luc Castera's blog post.  And for lack of a reliable smtp server setup, I'm just using GMail's SMTP server to send us the alert emails.  GMail SMTP requires SSL, and using monit version 4.8.x won't work.

Write a monit configuration file:

sudo touch /etc/monitrc

chmod 700 /etc/monitrc

Create a directory to hold individual monit monitoring configurations (for memcached:)

sudo mkdir /etc/monit.d

sudo touch /etc/monit.d/memcached.monit

The above creates an empty monit file for you to add some configurations.  Here is the monitrc file configuration I'm using (minus a few password related stuff):

set daemon 120 # Poll at 2-minute intervals

        set logfile /home/arthur/logs/monit.log # saves the log to a log file

        set httpd port 2812 and use address MY_IP_ADDRESS # this is monit's httpd server, shows you graphically what's happening

                allow MY_IP_ADDRESS # this is what IP's are allowed to access the monit page

                allow localhost # localhost is good for testing locally

            allow username:password # Allow Basic Auth

        set mailserver smtp.gmail.com port 587 username "emailname@gmail.com" password "gmailpass" using tlsv1 with timeout 30 seconds # this basically allows you to use gmail's smtp server.  tlsv1 gets things going in SSL.

        set alert globalemail@email.com # set this as a default email to send alerts to if you don't specify later on

include /etc/monit.d/* # includes your memcached.monit config file, and any others you write

So before you can test it out, since we're asking to include config files for stuff, we have to write one or else monit will complain it can't find any to load, so here's what I'm doing for memcached.monit:

check process memcached with pidfile "/home/arthur/logs/memcached.pid" # this is where the pid file will be

                start = "/usr/bin/memcached -u root -d -P /home/arthur/logs/memcached.pid" # this starts it with the root user, daemonized, and stores the pid in the file mentioned, the pid is important to be used all over.

                stop = "/bin/kill -9 cat `/home/arthur/logs/memcached.pid`; rm /home/arthur/logs/memcached.pid" # kills it and also removes the pid file to stop

                if failed host 127.0.0.1 port 11211 then restart # restart it if it dies on localhost on the default port of 11211

                if cpu usage is greater than 60 percent for 2 cycles then alert # if it uses too much cpu we'll send out an alert

                if cpu usage > 98% for 5 cycles then restart # if it uses tons of cpu, restart.  this should probably not be so high

                if 2 restarts within 3 cycles then timeout # timeout if you try too many times

        alert email@email.com # alert email

The cpu usage stuff is just some random stuff, so make sure you tune those to what you need.

Check your syntax by:

sudo monit -t

It should all check out OK, if not it will give you a bunch of errors.  Also if it can't find your monitrc config file, specify it with the -c flag.  If you did everything posted in the blog post the -c flag shouldn't be needed, as it'll find the config in the path.

Now big drumroll, start up monit

sudo monit

That's it, check the status with sudo monit status, and you can manually start memcached if not already with sudo monit start memcached.  Let me know if any of the info above is inaccurate or you have questions!

Tagged  //   code   memcached   monit  

Position Fixed and PNG on Internet Explorer 6

Internet Explorer 6, (excuse my language) is basically the bane of the existence of the internet.  The time spent wrestling with this car-with-square-wheels easily adds up to enough time to take a 2 month vacation.  If enterprises would just give their machines a refresh with IE7 or even FireFox, the web developer world would be a much better one.  Developers would be living much longer lives, have fewer grey hairs, have more girlfriends, and fewer wrinkles.  Seriously, why are we enslaved by IE6?

I have yet to find a perfect and elegant solution that can be applied to completely negate the neediness of IE6 and the "if lt IE 6" tag you use to load up specific ie 6 css rules.  The closest thing I've found to date is something my friend joe pointed me to.  Yes again, Joe is a source of a lot of good ideas.  It is a javascript library that fixes a bunch of stuff in ie 6: http://code.google.com/p/ie7-js/

The IE7.js file makes IE 6 perform more like IE7, and they also have an IE8.js that does the same for IE7 to IE8.  Problem is, it's definitely not a catch all and has a few problems, the biggest being that IE7.js works much better on ie6 than IE8.js does.  In fact I got my IE6 in much better shape than IE7 faster.

The PNG transparency fix it comes with is by far the best one I've found so far, not messing up any of my existing styles, working on background images (though not on tiling backgrounds), just by naming your png's that you want transparent with a -trans.png extension.

And amazingly enough, position fixed works like a charm in ie 6!  There are some other subtle fixes, like widths and such are less crazy, but still needs tuning.

I still spent almost 6 hours so far getting ie 6 to look and work better.  lots of javascript problems that can't be solved, even using prototype and scriptaculous.

Biggest caveat is that this is not css, it's javascript, so your DOM loads real ugly at first, and then the javascript kicks in and adjusts everything.  Load this file pretty early on so that other javascript doesn't start firing off without the fixes that the IE7.js provides.  I feel like the slow experience, and the shitty looks you get are deserved for using IE6.  Alas, I will be addressing all these issues into something more elegant.  More on that later... much later.

One day, our geek children will be amazed and have endless sympathy for their father developers and ie6, while they happily develop and visit the Maldives in their hovercraft or with the teleporter.

What am saying?  http://www.saveie6.com let the future feel the pain.

Tagged  //   code  

Engagement Party [photos]

Yes, a break from the geeky posts about weird coding stuff!  Last weekend my sister's friends, Andy and Eve, put together a great engagement party for my sister.  Between working out memcached errors and ie6 rendering issues, I was able to enjoy the party and take some pictures.  My girl Issa also got some sweet shots as well, links below:

Mine: http://www.flickr.com/photos/kinetic/sets/72157617681648803/
Slideshow: http://www.flickr.com/photos/kinetic/sets/72157617681648803/show/

Issa's: http://www.flickr.com/photos/luvableissa/sets/72157617626093219/



Cupcake






Happiness is simple




a girl, a d80, and the 50mm 1.8d





Cheers!





Always close





_____Oooo





_DSC5472





Engaged!!





Old and Young





Smiles

Tagged  //   photography  

memcached with passenger, ree, and the memcache-client gem

Memcached is pretty easy to setup, but there are a few items that are super strange.  This is how I set it up locally to test and on a production slice:

Production: Passenger 2.2.1, REE, rails 2.3.2, memcached, memcache-client gem, systemtimer gem, slicehost slice

Development: mongrels as usual, rails 2.3.2, ruby 1.8.6, memcached, memcache-client gem, systemtimer gem, Mac OS X Leapard

Development:

  • Install macports if you haven't already
  • sudo port install memcached
  • sudo gem install memcache-client
  • sudo gem install systemtimer
  • memcache -vv # this is the verbose for testing
  • I have yet to figure out how to get development working without memcached running when you don't care for it.

Production:

  • sudo apt-get memcached
  • sudo gem install memcache-client
  • sudo gem install systemtimer
  • memcache -d # this daemonizes it with the default IP to 127.0.0.1 and port 11211

Important Notes:

  • There is no configuration needed for apache/passenger.
  • memcache-client 1.5.0 is actually bundled with rails 2.1, but I would highly suggest upgrading to the memcache-client 1.7.2.  Read why here.  In a nutshell, it's WAY faster.
  • Check out his commit recently about system timer, this is extremely important for those running with REE.  He has not released this yet, but I've tried it on my slice and it works fine, so go ahead and edit your memcache.rb file with these changes.
  • Make sure you install all our gems with ruby enterprise.  Symlink your /usr/bin/ruby to the enterprise one, or make the enterprise ruby the first and only one to show up in your path.
  • Marshal serializes objects into memcached, and de-serializes them (is that the way to say it?) when you want to pull it out.  This way you can store more than just strings.  By passing in true as the third parameter of a fetch, you can do a raw add to memcache, but when you pull it back out, it will only come out as a string.  See more stuff later in this post about this.
  • Objects added or get'd from memcached need to be serializable!  Passenger gives you a horrible error message pointing to a line in memcache.rb where it does a Marshal.load or Marshal.dump, but tells you nothing else.  That's a good indication to check the objects you're returning in a fetch/add/get block to see if they are serializable.  If not write your own, see more further along in this post about it.
  • Passenger does smart spawning, which is great, but also freaks out memcached.  This is where we use memcache-client gem to do a reset whenever Passenger forks.  What smart spawning does, in short, is that whenever passenger needs a new worker process it loads it up with the an already loaded Rails application/framework, rather than loading the entire app and framework for each worker process.  It only does this once.  Really fast with REE and Passenger lined up.  REE improves this because it is copy-on-write friendly which means the worker processes will share as much memory as possible.  If you want to know more, read the two links in this bullet point that i mentioned.
  • How to re-establish connection with memcached in your rails app then specifically?  See below:

Setting up your production.rb to use memcached and to solve the smart spawning issue that Passenger has

# set cache classes to true
config.cache_classes = true
config.action_controller.consider_all_requests_local = false

# of course you want to perform caching
config.action_controller.perform_caching             = true

config.cache_store = :mem_cache_store
memcache_options = {
  :c_threshold => 10000,
  :compression => true,
  :debug => false,
  :namespace => 'a',
  :readonly => false,
  :urlencode => false

}

# require the new gem, this will load up 1.7.2 instead of using the built in 1.5.0
require 'memcache'

# make a CACHE global to use in your controllers instead of Rails.cache, this will use the new memcache-client 1.7.2
CACHE = MemCache.new memcache_options

# connect to your server that you started earlier
CACHE.servers = '127.0.0.1:11211'

# this is where you deal with passenger's forking
begin
   PhusionPassenger.on_event(:starting_worker_process) do |forked|
     if forked
       # We're in smart spawning mode, so...
       # Close duplicated memcached connections - they will open themselves
       CACHE.reset
     end
   end
# In case you're not running under Passenger (i.e. devmode with mongrel)
rescue NameError => error
end

And finally, the magical part of caching in your controllers:

CACHE.fetch('cachekey', 1.hour) { # block }

The above is using our CACHE global, that uses memcache-client 1.7.2.  memcache-client gem basically helps rails talk to memcached server.  No apache settings needed here at all.

The cache key should be unique enough so that the items in the block will be valid.

The second parameter is the timed expiration.  Be careful, Rails.cache.fetch accepts expiration as a hash parameter, :expires_in => 1.hour.  This is not the case for memcache-client, you must pass it in as a regular parameter.

The block can hold any ruby code you want.  It has access to any variables etc. normally accessible at this point.  The very last thing in that block is returned.  Great!  But something very important:

The returned object (and if a hash or array or an enum'd object, all objects there within) MUST be serializable.  If not, you're going to get some crazy ass error messages that says nothing about being serializable, and will give you headaches.  If something is not serializable, Marshalling will error out without telling you exactly what's happening.  You can write your own serialization for special objects to get around this, or save things in a custom hash if you don't really care about the entire object.  That custom hash would just hold all the values you need outside of the fetch block, and that hash can be returned.  here's an example of the error I got from Passenger when trying to hit an action that had an unserializable object returning:

[Sun May 03 23:14:57 2009] [error] [client 76.239.166.13] Premature end of script headers: amazon, referer: [ADDRESS_REMOVED_FOR_THIS_BLOG_POST]
[ pid=5227 file=ext/apache2/Hooks.cpp:546 time=2009-05-03 23:14:57.657 ]:
  Backend process 5255 did not return a valid HTTP response. It returned no data.
/opt/ruby-enterprise-1.8.6-20090201/lib/ruby/gems/1.8/gems/memcache-client-1.7.2/lib/memcache.rb:335: [BUG] non-initialized struct

If you see the above, immediately check the objects returning from the fetch block.

That's all for now, hope that was helpful for those with passenger, ree, and the memcache-client gem!

Big thanks to all the help from Mike Perham, who maintains the memcache-client gem (amongst other amazing feats), Michael Simons who wrote about the Passenger issues with more emphasis with solutions when using memcache-client gem, and all the folks at memcached google group and phusion passenger google group.  And big help from joe who helped troubleshoot all the code the whole time and dealt with all my crap.

Tagged  //   code   memcached   rails  

Rails cache store class and time-based expiry support with :expires_in option

Cache Store Class

Rails 2.x has an abstract cache store class, which is great to use for caching queries in the controller, but there are a few big gotchas that you'll need to figure out.  The fine print of the docs say little with a lot of links.  The basics of it are that you need to worry about your cache store implementation.  The docs recommends MemCacheStore.  I'm not sure what else you could use out of the box.

MemCacheStore uses memcached as cache storage, and is required to use :expires_in

:expires_in

So :expires_in won't work unless you specify in your settings that you're using the MemCacheStore implementation (or something similar) because MemCacheStore supports the :expires_in option with the write commands.  Otherwise your cache will not expire over time.  It's probably a better idea to use memcached and MemCacheStore on production as it's probably the best solution currently, than to write something to the database that saves off cache times and such.

If anyone has other suggestions to better solutiosn other than MemCacheStore, please post!  This is the only solution I've found looking through the docs.


Tagged  //   code   rails