tags:

views:

97

answers:

2

Couchdb is great at storing and serving data, but I'm having some trouble getting to grips with how to do back-end processing with it. GWT, for example, has out of the box support for synchronous and asynchronous call backs, which allow you to run arbitrary Java code on the server. Is there any way to do something like this with couchdb?

For example, I'd like to generate and serve a PDF file when the user clicks a button a web app. Ideally the workflow would look something like this:

  • User enters some data
  • User clicks a generate button
  • A call is made to the server, and the PDF is generated server side. The server code can be written in any language, but preferably Java.
  • When PDF generation is finished, the user is prompted to download and save the document.

Is there a way to do this with out of the box couchdb, or is some additional, third-party software required to communicate between the web client and backend data processing code?

EDIT:Looks like I did a pretty poor job of explaining my question. What I'm interested in is essentially serving servlets from Couchdb similarly to the way that you can serve Java servlets along side web pages from a war file. I used GWT as an example because it has support for developing the servlets and client side code together and compiling everything into a single war file. I'd be very interested in something like this because it would make deploying fully functional websites a breeze through Couchdb replication.

By the looks of it, however, the answer to my question is no, you can't serve servlets from couchdb. The database is set up for CRUD style interactions, and any servlet style components need to either be served separately, or done by polling the db for changes and acting accordingly.

+1  A: 

GWT has two parts to it. One is a client that the GWT compiler translates to Java, and the other is a Servlet if you do any RPC. Typically you would run your Client code on a browser and then when you made any RPC calls you would contact a Java Servlet Engine (Such as Tomcat or Jetty or ...) , which in turn calls you persistence layer.

GWT does have the ability to do JSON requests over HTTP and coincidentally, this is what CouchDB uses. So in theory it should be possible. (I do not know if anybody has tried it). There would be a couple of issues.
CouchDB would need to serve up the .js files that have the compiled GWT client code.
The main issue I see in your case is that couchDB would need to generate your PDF files, while couchDB is just a storage engine and does not typically do any processing. I guess you could extend it if you are any good with the Erlang programming language.

Romain Hippeau
I'm not really interested in running GWT on couchdb, I'm actually interested in replicating the functionality of an RPC call. Is there any equivalent of the Java Servlet Engine for couchdb?
TwentyMiles
@TwentyMiles What I tried to explain is that you could make calls to CouchDB, but that would only be data access (CRUD). To be able to do any processing you will need to have a Servlet Engine that gets the data from CounchDB and then massages it to produce PDF. Another point I made is that you could add an Erlang module in front of CouchDB and call that to do your processing (Of course that would be non trivial)
Romain Hippeau
+1  A: 

Here's what I would propose as the general workflow:

  1. When user clicks Generate: serialize the data they've entered and any other relevant metadata (e.g. priority, username) and POST it to couchdb as a new document. Keep track of the _id of the document.
  2. Code up a background process that monitors couchdb for documents that need processing.
  3. When it sees such a document, have it generate the PDF and attach it to that same couch doc.
  4. Now back to the client side. You could use ajax polling to repeatedly GET the couch doc and test whether is has an attachment or not. If it does, then you can show the user the download link.

Of course the devil is in the details...

Two ways your background process(es) can identify pending documents:

  • Use the _changes API to monitor for new documents with _rev beginning with "1-"
  • Make requests on a couchdb view that only returns docs that do not have an "_attachments" property. When there are no documents to process it will return nothing.
    • Optionally: If you have multiple PDF-making processes working on the queue in parallel you will want to update the couch doc with a property like {"being-processed":true} and filter these out the view as well.

Some other thoughts:

  • I do not recommend using the couchdb externals API for this use case because it (basically) means couchdb and your PDF-generating code must be on the same machine. But it's something to be aware of.
  • I don't know a thing about GWT, but it doesn't seem necessary to accomplish your goals. Certainly CouchDB can serve any static files (js or other) you want either as attachments to docs in a db or from the filesystem. You could even eval() JSON properties you put into couch docs. So you can use GWT to make ajax calls or whatever but GWT can be completely decoupled from couchdb. Might be simpler that way.
duluthian