The Adept Development System has as its goal the use of corporate skills and technology to produce shrink-wrap software. One of the core design decisions was to use a DHTML-enabled browser as the GUI. This means that the Adept server is a web/application server in the same family as Tomcat. There are differences: Adept has been developed from the ground up to serve a DHTML client, not a Java Server Pages intermediate.
The Server
At the core there is a Server class that runs in its own thread until it's asked to be closed. The main thread normally just waits for the server thread to complete. The separate threading is mostly a convenience for testing, where the test methods want to spawn a server and send it stuff to test. So the server class has the simple function of waiting for client connections, then spawning off a new Connection object to service them. Some servers attempt to minimise the expense of starting a new thread for each connection by pooling connections, but I considered this a case of the benefit not being enough to cover the risks. Modern HTTP 1.1 protocols keep the same connection for use for as long as they can - typically minutes but often for much longer. And on the other side of the coin, starting a clean thread for each new connection ensures that data won't accidentally survive to be used by another thread. This model is inherently multi-user.
The Connection
Each connection also runs in its own thread. This allows the same server to service multiple connections from the same or different clients. As a standard, most browsers make 2 concurrent connections to the server. A connection survives until the client closes the socket or until it is unused for the timeout period of 5 minutes. The browser will at times close the connection and ask for a fresh one using internal rules of it's own.
The Request
The connection then waits for a request from the client. The first thing a request does is attempt to associate a session. The URL of the request is then parsed. If the command ends in slash(/), the default action is looked for. If a normal action cannot be associated a slash is added and the default action attempted again.
For an action, default or no, the request will first look at the file type of the request - being everything before the ? or end of request back to the last full stop. If a servlet is registered against a file type (as with .js), it is used. Otherwise, if it's one that the client has registered it's sent as-is to the browser. If neither of these occur, the request looks for a Java class that extends from ActionInterface. If all else fails, it's sent back to the client to see if it can be rendered as-is.
The Session
A request looks for a specific browser cookie for the session ID. If there is no cookie a new one is created to send as part of the response. In the disconnected client/server environment, this is the way we keep data for the session - by associating it with a unique cookie. By default this cookie is called
AdeptSession - although it can be changed by setting a property called
session.cookie.
The session name can be either an automatically generated name for anonymous connections, or the user name once the user has logged in. The anonymous name is a persistent cookie so that related data is kept permanently. If a user logs in this cookie is overridden by a browser session cookie that will be lost when the browser is closed or the user logs off. It's possible to make this cookie persistent for secure machines.
Default Actions
If default actions are given a path only, the server will look for a default action to run - being either a servlet called
Index, an external program called
index.cgi, or html documents called
index.html or
index.htm. In general it's better to specify the full action rather than ask the system to search for it.
Registered Servlets
Normally any file with an extension is sent to the browser/client for rendering. This be anything from documents to text files, images, style sheets or JavaScript. Occassionally it will be useful for server classes to know about or filter the information. Currently the only existing example within adept is in loading JavaScript classes. They are registered against a servlet called
LoadJavaScript that adds a call to a
JavaScript._afterLoad(), which Adept uses to sequence loads and initialisation of Javascript.
Each class is registered in server code using LoadJavaScript.Server.register(), giving it the file extension and a class with an ActionInterface to do the work.
Running a Servlet
A servlet is a class with a
com.marringtons.adept.action.ActionInterface interface. Its execute method is called wrapped in a transaction. Any exception will cause a rollback, while a clean return will trigger a commit.