Do you ever feel like the big-name web frameworks have grown too much, that they're bloated from an endless diet of new features?
Here's fast relief for that bloated feeling: Sinatra, a lightweight Ruby web framework. Minimal docs, but $10 gets you traction from a couple of excellent screencasts.
Monday, March 2, 2009
Monday, February 23, 2009
Make An Effort(s)
I wrote some simple code today: a batch job that counts the number of items in a queue, then emails the count to a couple of people. My first version sent a message like this:
Then I smacked myself and dove back into the code. Now the message looks like:
or:
Maybe ten minutes to code and test, and I feel better. The
There are 3 item(s) in the queue.
Then I smacked myself and dove back into the code. Now the message looks like:
There are 3 items in the queue.
or:
There is 1 item in the queue.
Maybe ten minutes to code and test, and I feel better. The
item(s) dodge is lazy, and looks so cheesy.Friday, February 20, 2009
Lotus Domino - Sometimes Store And Forward Wins
In my day job, I babysit a fairly large Lotus Domino web application – call it ELF – at a very large financial services company. I do all the development and most of the production support.
Some parts of ELF work like this:
All true, but this basic store and forward architecture has a real advantage: it's more robust than the typical web application (call it TWA). TWA looks something like this:
Domino OTOH is a large, monolithic monster. It provides everything - the web server, the application server, the database server, even a batch scheduler. All in one server, on one machine. This eliminates a lot of the risks. If the web server is up, then the database server is up, and the web server can talk to it. If Domino can serve up pages, it can store the data that come back.
For ELF, this means independence from the back-end relational databases. If they crash, if they go off-line for maintenance, if there's a network problem, ELF doesn't care. It keeps accepting customer requests and storing them in Domino. Every couple of hours, it tries to reach the relational databases. If they're available, fine – it transfers the requests. If not, no worries, it tries again later. And the website stays up.
Here's a real-life example, from last week, that got me thinking about all this. I mentioned configuration risk. In TWA, the application server probably stores its database credentials – userid, password – in a secure configuration file. But what if some overzealous dolt disables the database userid? That kind of thing happens in big companies. And when it does, TWA stops working, till someone figures out what happened and gets it fixed. Again, in a big company, that can take a surprisingly long time.
But when this happened to ELF, it kept rolling along. We didn't even know there was a problem till the people on the relational database side noticed they weren't seeing any inserts. We looked into it, found the credentials problem, and got it fixed. But the userid went bad on a Friday, when I was out. By the time we got the problem fixed, it was Tuesday - five days. All that time, ELF accepted customer requests and stored them in Domino. Once the credentials were fixed, it transferred all the requests. No data loss, no unhappy website users.
TWA can't load-balance around a problem like this. But let's reshape TWA a bit. Let's have the application server write all the front-end data into a local store, on the same machine. Maybe it uses the filesystem, maybe sqlite. Whatever's fast and reliable. After that, let some batch job deal with it. Any problems reaching the “real” datastore are now in the background. The application server can still capture the user's data and send good news back to the browser.
Obviously, if your customers are trading stock, you don't want to do this. But if they're buying books or T-shirts, maybe you can get away with it. And it's a whole lot better than “Try again later.”
Some parts of ELF work like this:
- A customer request comes in through the web front end. (ELF handles about a dozen different kinds of requests);
- The web server stuffs the request into a Domino database;
- A batch job moves the request to a relational database.
All true, but this basic store and forward architecture has a real advantage: it's more robust than the typical web application (call it TWA). TWA looks something like this:
- Web server running on one machine;
- Application server, a separate piece of software, running as a separate process on the same machine, or on another machine;
- Database server, a separate piece of software, almost certainly running on another machine.
Domino OTOH is a large, monolithic monster. It provides everything - the web server, the application server, the database server, even a batch scheduler. All in one server, on one machine. This eliminates a lot of the risks. If the web server is up, then the database server is up, and the web server can talk to it. If Domino can serve up pages, it can store the data that come back.
For ELF, this means independence from the back-end relational databases. If they crash, if they go off-line for maintenance, if there's a network problem, ELF doesn't care. It keeps accepting customer requests and storing them in Domino. Every couple of hours, it tries to reach the relational databases. If they're available, fine – it transfers the requests. If not, no worries, it tries again later. And the website stays up.
Here's a real-life example, from last week, that got me thinking about all this. I mentioned configuration risk. In TWA, the application server probably stores its database credentials – userid, password – in a secure configuration file. But what if some overzealous dolt disables the database userid? That kind of thing happens in big companies. And when it does, TWA stops working, till someone figures out what happened and gets it fixed. Again, in a big company, that can take a surprisingly long time.
But when this happened to ELF, it kept rolling along. We didn't even know there was a problem till the people on the relational database side noticed they weren't seeing any inserts. We looked into it, found the credentials problem, and got it fixed. But the userid went bad on a Friday, when I was out. By the time we got the problem fixed, it was Tuesday - five days. All that time, ELF accepted customer requests and stored them in Domino. Once the credentials were fixed, it transferred all the requests. No data loss, no unhappy website users.
TWA can't load-balance around a problem like this. But let's reshape TWA a bit. Let's have the application server write all the front-end data into a local store, on the same machine. Maybe it uses the filesystem, maybe sqlite. Whatever's fast and reliable. After that, let some batch job deal with it. Any problems reaching the “real” datastore are now in the background. The application server can still capture the user's data and send good news back to the browser.
Obviously, if your customers are trading stock, you don't want to do this. But if they're buying books or T-shirts, maybe you can get away with it. And it's a whole lot better than “Try again later.”
Saturday, January 31, 2009
Clojure and MySQL, continued
I've been working through the Data Access section of the Clojure in the Wild chapter in Stuart Halloway's Programming Clojure. Here's a MySQL version of the last-created-id form:
(defn last-created-id
"Extract the last created id. Must be called in a transaction
that performed an insert. MySQL version."
[]
(:last_created_id (first (sql-query "select LAST_INSERT_ID() as last_created_id"))))
Thursday, January 29, 2009
Clojure and MySQL
Here's the magical connection incantation to get Clojure and MySQL talking:
Assumptions - you're using
Incidentally, the Connector/J license defaults to GPL, so it may contaminate your application like ice-nine. Hail Bokonon!
(def *db* {:classname "com.mysql.jdbc.Driver"
:subprotocol "mysql" :subname "//your-server/your-db"
:user "your-user" :password "your-password"})
Assumptions - you're using
- Stephen C. Gilardi's clojure.contrib.sql library, and
- MySQL's Connector/J JDBC driver, with mysql-connector-java-5.1.7-bin.jar in your Clojure classpath.
Incidentally, the Connector/J license defaults to GPL, so it may contaminate your application like ice-nine. Hail Bokonon!
Subscribe to:
Posts (Atom)