Busted Mug

A blog that documents solutions to the most frustrating problems that occur during development in technologies such as Java, XML, AJAX, SQL, CSS and others that make me want to throw my coffee mug against the cube wall.

Tuesday, March 25, 2008

Database operation failed. ERROR: library routine called out of sequence DETAILS: not an error

I ran into this guy "Database operation failed. ERROR: library routine called out of sequence DETAILS: not an error" while working on a google gears application. The error comes from SQL Lite (the technology under the sheets of gears' data store). There didn't seem to be much documentation on the web to help but finally from placing lots of alert statements (don't you love javascript?) I narrowed it down to a call to rs.next(). I knew the data set would be empty so I immediately suspected I was doing something wrong with checking for the end of the RS.

My suspicions were confirmed when I found the following code block at http://code.google.com/apis/gears/api_database.html#ResultSet:

while (rs.isValidRow()) { console.log(rs.fieldName(0) + " == " + rs.field(0)); rs.next(); } rs.close();

It appears I missed something basic. Unlike both Oracle and MySQL, when grabbing a new row in SQL Lite in Gears there isn't any automatic evaluation that the row is valid. You have to explicitly call the isValidRow() method. This leaves out the nice and tidy while(rs.next) loops that we all love so much. The first row comes pre-loaded then you have to next after each use. As the dude would say "That's a bummer, Man." I hope I head off someone else freaking out over this novice problem when working in Gears. Maybe SQL Lite/Gears will eliminate the need for the call some day, until then...

Saturday, March 01, 2008

Google answers online state dilemma with non-answer

As I discussed in my previous post There isn't a way to maintain online state with Google Gears. I just found an entry on Google Code which addresses the subject when it comes to database stores. I totally understand Google's point about wanting developers to ensure synchs are reliable and not assume online = success. That still doesn't address my issue with LocalServer rather than the Database module of Gears.

A bit frustrating also is to see that on the same page Google provides essentially the same code I discussed previously to ping the server with AJAX to verify that it is available. GaH! Wasted effort!

I have to say that I do think Google is cutting off it's nose to spite it's face here. While an isOnline() function might be abused when it comes to the local database, it's entirely necessary (as I've demonstrated) for the localServer which is 1/3 of the gears trinity. In addition, I've seen time and time again that you can't use technology to make programmers do their job correctly (I've tried). You have to empower them to make good design decisions on their own, warn them of the pitfalls, and then let them deal with the consequences if they don't do their job well. It's an annoying fact of life in IT (I would know, I've done a lot of cleanup after bad programmers). That's my 2 cents anyhow.

Labels: , , , , ,

Google gears and the online state dilemma

As I mentioned in my previous post I've been working with Google Gears as of late. Being a greenhorn to this technology (as nearly everyone is since it's pretty new) I found myself considering some fairly serious design questions. The most interesting was "how do I tell if a user is in offline mode (pages and data cached) but has the ability to switch over to online mode?"

Now of course whenever you talk about "modes" in an application it is natural to think about a state machine. That gets a little dicier with the new paradigm introduced with Gears. Since gears runs purely in javascript with a little interaction with the browser plugin, I decided that making an AJAX request for a file that doesn't get cached (as defined in my gears manifest file) was best. If I got the proper contents of that file then I knew the person could swap to online mode, if not then I know they aren't connected. Simple right?

So I thought. Once I whipped up my code I could offline and online my pc and the app was stateful, except of course for a little lag that the ajax request took to timeout when it wasn't ever going to get a response from the server. I included validation based on state to see if I would let the user remove their cached pages and get the online one and everything was happy.

Then I decided to take a look at what I'd done pretending to be a non-technical user. I offlined my app and then watched it. During the lag I noticed that the app state was still online (meaning you could validly switch to online mode) because the first AJAX request hadn't failed yet. So I thought to myself "what if the user took this literally and assumed they were connected via wifi or something and tried to go online?"

The answer: DEATH. Ok not really death but my state machine happily checked its state, saw that it was online, removed all the cached pages and tried to get at the online version of the page. This of course resulted in a 404 as the user wasn't actually connected. No good. My first instinct was that I had to prevent this from ever being a possible scenario because a user would probably freak out.

The half-measure I took to do this was to break out the cache-removing code and not include it on the manifest. Now the user can attempt to remove their cache, but if they aren't actually online they won't find that page and get a 404, but they can back up and the app is still happily serving up cached content while they continue to be offline.

I'm happy with this but not completely. It seems to me (at least so far) that there's no way to conquer this part of the paradigm shift that gears introduces into web applications. No matter how you code around it, the web layer always has a degree of latency associated with it that will allow a window for 404 messages. I hate for the user to see that. I'll update if I figure out a way around this loophole, please comment if you know one ;)

Labels: , , , , , ,

Simple, cross-browser threading (forking) in php

I recently had a need to do some threaded processing in php while working on a Google Gears prototype application. As is often the case with gears, when synching the data with the online database, it'll take a while. If you're doing this explicitly and not in the background, it's nice to at least be able to update the user of the process' status using AJAX. This was my need for threading (forking in php). I wanted to run a thread to handle the update of the database and let the user sit on a page that keeps checking on the progress and updating a progress bar. Intuitive, right?

Since it had been a while since I've worked with forks in PHP I figured I'd check out Google for a tutorial on the best practice on the subject. Whoa. I got like 90 different methodologies and hardly any worked for all scenarios and cross-platform (I don't know if my project will end up on a server with windows under it or *nix). That is, until I found this blog entry by a chick named Katy. She demos the following code:



To create a fork:
function startFork($path, $file, $args)
{
  chdir($path);

  if (substr(PHP_OS, 0, 3) == 'WIN')
    $proc = popen('start /b php "' . $path . '\\' . $file . '" ' . $args, 'r');
  else
    $proc = popen('php ' . $path . '/' . $file . ' ' . $args . ' &', 'r');
 
  return $proc;
}

To get data from the fork:
while (!feof($proc)) {
  $data = fgets($proc);

  // Do something with the data
}
This methodology is great because it seems to always fit. It's pretty easy to understand too. It does involve some OS calls but has conditions for for windows and *nix, which is ok by me. It's a simple method that starts a new process for the thread. I plan to implement post haste. I'd recommend this if you need to do some threading (forking, I wish Java and PHP would get on the same page as far as terminology is concerned).

Labels: , , , , ,