Tuesday, November 30, 2010

Pascal(a)'s Triangle

I've been toying with scala for a bit now. Not as much as I'd like to, and not often for work, but just because I like what little I've seen. As a bit of a college CS course throwback, I wrote a little scala script to print Pascal's triangle. The goal of these exercises is to code in good scala style, using scala as best possible. So, if you happen to be a scalawiz and see some un-scala construct, please point it out and suggest something more scala-ish.



Saturday, February 13, 2010

Flex Activate / Deactivate Events on OS X

In JamLegend, it would be nice to auto-pause the game when the user switches focus to another application. You'd think it would be very simple to detect if Flash player currently has focus, but the recommended methods are unreliable cross-platform.

Findings (so far)
  • Chrome, Firefox, and Safari receive activate and deactivate events if the browser loads the SWF directly, but NOT if the SWF is loaded inside of an HTML page.
  • The method of loading the SWF is inconsequential; e.g. JavaScript vs. HTML tags.
  • When the SWF is loaded directly, activate is not dispatched when re-focusing on the browser by clicking the flex app; a second click is required.
This is really a pain. One suggested hack is to look for the MOUSE_LEAVE event (when the user moves the mouse off of the flex app). That works well when UI elements are draggable and you need to handle the case of the mouse leaving the flex app while dragging, but it isn't a valid indicator of whether the flex app still has focus. For example, in JamLegend, the user can move the mouse anywhere and they can still play as long as the flex app has focus (thus receiving key events).

There might be a big hack somewhere, utilizing activate and deactivate events for Windows, plus a combo of JavaScript focus events and mouse position for OS X, but I haven't figured it out yet...

System Details
  • OS X 10.6.2
  • Flash Player 10,0,42,34
  • Chrome 5.0.307.7 beta
  • Safari 4.0.4
  • Firefox 3.5.5.

Resources

Wednesday, January 27, 2010

Flex Binding "Gotcha!"

Somewhere online, I saw a comment saying that binding in Flex is "evil magic" and should be avoided except in the simplest of cases. Though I could see where the author was coming from in theory, it wasn't until today that I encountered this in practice.

In short, setting a bindable variable to a field of a bindable class binds the variable to the value referenced by the field, not to the reference in the bindable class. Get it? The whole pass by value vs. pass by reference thing. Here's an example (ignore the use of the default package):

Class A:
package
{
[Bindable]
public class A
{
public var val : int;
public var b : B;

public function A()
{
val = 0;
b = new B(0);
}
}
}

Class B:
package
{
[Bindable]
public class B
{
public var val : int;
    public function B(v:int)
{
this.val = v;
}
}
}

MXML Test:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

<mx:Button click="onClick()" label="Click Me" />
<mx:Text text="A: {myA.val}" />
<mx:Text text="B: {myB.val}" />

<mx:Script>
<![CDATA[
[Bindable] var myA:A = new A();
[Bindable] var myB:B = myA.b;

function onClick() : void
{
myA.val += 1;
myA.b = new B(3);
}
]]>
</mx:Script>
</mx:Application>

At launch, the text elements both have the value 0. But, after one click of the button, what is the value of myB.val?

I don't think I'm alone on this, but maybe I am. In any case, I expected myB.val to be 3, because myB was assigned to myA.b and A is a [Bindable] class. When I changed the value of myA.b, I expected myB to reference new instance of B that myA.b now referenced.

Turns out it doesn't. After one click of the button, myB.val == 0. Why? Because myB is still bound to the original instance of B referenced by myA.b at the time myB was assigned, rather than whatever instance of B that myA.b might reference in the future.

Bummer. If only myB was a pointer...

Thursday, October 29, 2009

Toggle Hibernate "Show SQL" at Runtime

Okay, the title is a bit deceiving. As far as I know, you cannot modify the value of the configuration property "hibernate.show_sql." However, that does not prohibit you from toggling at runtime whether SQL statement are output to your log files.

Why would you want to do this?
Because turning on "show_sql" will flood your logs with all the SQL generated by hibernate, making it difficult to find a particular section you might be debugging or optimizing. Being able to toggle the output of SQL allows you to enable it just for the sections of code you are investigating.

First, the solution, then I'll get to why:


import org.apache.log4j.*;

...

Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
sqlLogger.setLevel(Level.DEBUG);

... do your stuff ...

sqlLogger.setLevel(Level.OFF);

So what's going on here?
The key is knowing what "show_sql" does and that it is not the only way to log the SQL statements generated by hibernate. Namely, "show_sql" sends all SQL to the standard output, but hibernate also uses Apache Commons Logging. So, as long as you configure commons logging to use an underlying logging framework that supports changing log levels at runtime, you can toggle the output of SQL by getting a hold of the "org.hibernate.SQL" logger and bending it to your will.

Friday, April 10, 2009

FragmentCache part duex: Cleaning

I realized that I forgot to address an additional, critical, issue with fragment caching: cleaning out expired fragments.  A fragment cache implemented as I described in my last post would update expired fragments when requested, but what about expired fragments that aren't requested?  

If you externalized the cache itself, then your cache will likely support LRU or LFU expiration policies. But, if you're using a in-memory cache in the Java heap space, well, that's a memory leak.  If you cache a lot of fragments, failing to clean the cache is a recipe for maxing out the old generation space and thus causing Full GC's to run back-to-back, collecting just enough space to limp along, but not do any good, until eventually your application becomes non-responsive.  So, an additional requirement for an in-memory fragment cache is that you monitor the usage and have a cleaner task which runs, say, once an hour, to remove fragments that have expired and are not currently locked for update.  Doing this efficiently with a large cache requires using a data structure that supports thread-safe concurrent access, so as to avoid locking the whole cache while cleaning and maintain high throughput.  

Sunday, April 5, 2009

The JamLegend Fragment Cache

Abstract
The benefits of fragment caching are pretty well-known.  If you haven't come across it before, the concept is simple:  cache portions of the page to lighten database load by reducing or eliminating redundant queries.  Often, this can be the "most bang for your buck" type of cache. How long a fragment should be cached is a function of the expense of generation, frequency of changes, and the frequency of access.  Ideal fragments for caching are the most accessed and most expensive to generate.

The fragment cache I'm going to discuss is the implementation of the FragmentCacheTag JSP custom tag, in J2Free, the one-day-to-be-open-source framework on which JamLegend is built (you can find more info on J2Free here, and in a few of my previous blogs).  

JamLegend Examples
The "Popular Today" songs lists on JamLegend are a little expensive to generate, shown on all the highest trafficked pages, and don't change too quickly.  As such, we cache that list for 5 minutes, saving us a lot of queries but keeping the list rather dynamic.  On the other extreme, comments change constantly and need to be much more dynamic.  We cache comment threads for 30 seconds.  When you have a high number of concurrent users, even a 30 second cache can save you a lot of queries without sacrificing liveliness.

The Code Samples

<cache:fragment timeout="${30 * 1000}">
Simple cache based on a timeout of 30 seconds.
</cache:fragment>

<cache:fragment timeout="-1" condition="${size(items)}">
Simple cache with no timeout, using instead an additional attribute to refresh the cache when the size of the collection "items" has changed since the cache was last updated. This works well in situations where data changes rarely, and you want it to be available immediately upon change.
</cache:fragment>

<cache:fragment timeout="${30*1000}" disable="${devMode}">
Simple cache based on a timeout of 30 seconds but with an attribute to disable the cache if devMode is flagged. Here, devMode is a application scope attribute set when the server starts up. It's nice to be able to selectively disable certain caches for testing, and have them enabled live without having to change any code.
</cache:fragment>

The JamLegend FragmentCacheTag also supports an additional application scope attribute to globally disable all caching.  One of these days, I'm going to get around to changing the timeout to be specified in seconds, instead of milliseconds; just hasn't happened yet... 

Fragment Caching "Gotchas"
Two of the first problems you'll run into with fragment caching are:
  1. logged in vs. logged out users
  2. concurrent cache refreshing
The first is a problem you're going to encounter simply by using a fragment cache.  The second, on the other hand, you'll only run into if you're building your own fragment cache; if you use the J2Free FragmentCacheTag described here, it will be taken care of for you.

Adding Dynamic Capabilities to Cached HTML 
Sometimes ideal candidates for fragment caching have display differences when users are logged in.  For example, caching comment threads:  logged in users see a "report" link, whereas logged out users do not.  Since a fragment cache holds the generated HTML, as opposed to an object cache or query cache, it isn't easy or efficient to modify the fragment based on logged-in status (though, it's not impossible and I'd appreciate any elegant approaches).  Fortunately, JavaScript comes to the rescue.  

On JamLegend, a "report" link is included in the generated HTML for comment threads whether the user is logged in or not, with style="display:none;" to hide it initially.  Then, if the user is logged in, we use a little JavaScript on page load to show all the report links, otherwise they stay hidden.  This is the same technique used by 37Signals (see JavaScript Makes Relative Times Compatible with Caching).  Since we also check server-side that a user is logged in before allowing them to mark a comment as spam, there isn't a significant downside to having the hidden spam links for users who are not logged in.

Preventing Concurrent Refreshes
If you're caching a fragment because it's expensive to generate, the last thing you want is a few hundred users concurrently refreshing the fragment triggering a few hundred concurrent expensive queries.  So, how do you prevent this?  The first question you have to answer is this:
When user A has triggered a cache refresh, what should happen to other users who hit the same fragment?
Should they:
(a) Head over to user A's thread, wait for user A's thread to complete the query, and then ask for the result?  or,
(b) Should they just see that user A is refreshing the cache and so grab the last cached fragment and return immediately?
Both are acceptable answers, but which you choose depends on how stale you allow your fragment to be.  In case A, you can serve the most recent fragment to an unlimited number of callers while still only generating the fragment once.  Since user A triggered the refresh first, that thread is necessarily ahead of the other threads, so the others will still return is less time than if they were the sole thread refreshing the cache.  In case B, the subsequent threads can return immediately serving the last version of the fragment while assuming that user A's thread will refresh the cache.

For J2Free's FragmentCacheTag, I chose scenario B on the reasoning that the fragment is cached to begin with because it is not crucial that it be 100% up-to-date.  Ergo, what's one more minute with the old fragment?  At some point, I want to add this as an optional attribute, something to the effect of:

<cache:fragment timeout="600000" waitOnRefresh="true">
... where waitOnRefresh enabled would indicate that the cache should not server the last fragment while being refreshed, but rather attach itself to the thread conducting the refresh and get the result when complete.
</cache:fragment>

Obviously, the above only applies to multi-threaded servers.  There is an additional case, though, that applies to single and multi-threaded servers:  what happens in a cluster?  How do you prevent concurrent refreshes when you're running multiple servers?  A few options are: 
  1. Store fragments in a distributed cache, like ehcache, JBoss cache, or memcached, using replication instead of invalidation.  However, there is still the possibility of instance A triggering a refresh then instance B triggering a refresh before instance B received the updated fragment from instance A.  This window could be decreased by replicating a lock-for-update on a fragment, rather than waiting for the complete fragment, but not closed entirely.
  2. Using a central, synchronized cache would remove the race-condition from situation 1, but at the cost of decreased throughput.  Depending on the location and network access to such a cache, it may or may not be worth it.  Ping times intra-ec2-zone are only 1-2ms between instances, so it might be worth it to add a few ms to each request to avoid concurrently executing an expensive query.
  3. Use a distributed cache, as in situation #1, but only allow 1 instance to refresh the cache.  This may or may not work depending on how well you split requests between instances.  You certainly wouldn't want users on instance B to continue to receive stale data because no user on instance A has triggered a cache refresh.  This strategy may work well for pages that are guaranteed to be accessed on each instance.
I welcome comments on any additional solutions to preventing concurrent cache refreshing in a cluster.

Thursday, November 20, 2008

Another Flex Cross-Browser Incompatibility (OS X ProgressBar display)

So, Flash is supposed to solve all our cross-browser issues... only it doesn't.  My most recent discovery relates to the visual look of a ProgressBar between OS X and Windows when the mode = ProgressBarMode.MANUAL and indeterminate = true.

To illustrate this, we'll start with the following MXML component:

<mx:progressbar x="10" y="10" id="progress" labelplacement="bottom" indeterminate="true" enabled="true" minimum="0" maximum="100" label="" width="210"/>

With some styling applied, the result is this:


Now, let's say that we want to use the ProgressBar for some non-indeterminate (er, determinate) purpose, like loading some data from a server. So, let's do this:

progress.indeterminate = false;
progress.mode = ProgressBarMode.MANUAL;
progress.setProgress(0,100);

someLoader.addEventListener(ProgressEvent.PROGRESS,someProgressListener);

Great. Now, someLoader will load something, and someProgressListener will keep us up-to-date about the progress. So, say we've loaded all the data and now we're doing some processing, the progress of which we don't know since our processing function is synchronous and does not dispatch ProgressEvents. So, we want to set indeterminate back to true so that our users will know something is still happening but not show possibly incorrect progress with a determinate ProgressBar. So, let's do this:

progress.removeEventListener(ProgressEvent.PROGRESS,someProgressListener);
progress.indeterminate = true;

WTF! Now our ProgressBar looks like this:


In Firefox and IE on Windows, the ProgressBar looks identical to before, which is the expected behavior. But in Safari (at least) on OS X, we have this monstrosity. What happened? Shouldn't Flash look identical in any browser? Well, apparently it doesn't.

Fortunately, this isn't unfixable.  In fact, it's a very simple fix, though it makes zero sense to me why this changes the visual display.  Just set progress.mode = ProgressBarMode.EVENT. Turns out that this ugly displacement only occurs in OS X if (progress.mode == ProgressBarMode.MANUAL && progress.indeterminate). Oh well, something to chalk up on the list of cross-browser differences in Flash.

On another note, remember that progress.setProgress(num,total) will not do anything unless you have set progress.mode = ProgressBarMode.MANUAL. This is another thing I think is ridiculous, but the ProgressBar will ignore any calls to setProgress if mode != ProgressBarMode.MANUAL. I understand that the different ProgressBarMode settings will instruct the ProgressBar where to expect progress changes from, but it still seems odd to fully ignore calls to setProgress WITHOUT throwing any kind of error or warning when mode != ProgressBarMode.MANUAL.

Versions:  This was discovered in OS X 10.5, Flash MAC 10.0.12.36 (debug), Safari 3.2.1.