tiscaf http server, overview
Don't miss! The next tiscaf development phase takes place
here: https://github.com/gnieh/tiscaf
tiscaf - is an http server written in and intended to be used with
the Scala programming language.
motivations
Very often a current software exosphere makes almost impossible to do things a simple way. Almost all
developers are under heavy pressure of dependency on J2EE and accompanying frameworks with dozens of external
libraries (how many megabytes do those external jars take?). All you know these software monsters with infinite
dependencies trees... I have decided I need more freedom.
OTOH, if you like to spend your life dealing with extraneous-designed XML-files (rather
coding) and/or to satisfy multiple APIs presenting good ideas (even if last ones are indeed good), be
warned - tiscaf lives in another world.
The server has just what you need to handle an HTTP request, no more. I treat the server as a low-level
self-contained "assembly" module (being used instead of servlet engine) which is easy to embed into any
application as well as to wrap with, say, own templating framework, with any dispatching model (besides included
helper for tree-like URIs space), with this or that (besides default) execution environment (say, Comet-like),
and so on.
features
- nio - nio using permits resources managing.
- dynamics - besides default execution pool it is possible to use
own execution environment for each request handler.
- full streaming - the server allows a streaming in both directions;
say, you can download and upload ISO images.
- dispatching - requests dispatching is limited with your imagination only.
- multiport - listening to multiple ports is possible.
- static content - file system and in-jar resources retrieving is supported out of the box
(with files/directories browsing).
- connections - persistent connections are supported.
- output - raw (content-length is known), buffered, gzipped (as a case of buffered),
chunked - all modes are supported.
- methods - POST/urlencoded, POST/multipart (with falling POST back to octets) and
GET methods are supported.
- sessions - via URI path extensions or cookies are supported.
- config files - are absent.
- codebase - ~90KB in Scala.
- depends on - nothing (again: nothing).
- licensing - LGPL.
benchmarking
Some numbers are presenting here to take you a taste of the server's performance.
In particular, you can be interested in this benchmarking results.
Shortly, both server and ApacheBench are running on the same workstation (Intel i5 760 at 3.2GHz).
Operating system is Arch Linux with default TCP/IP stack settings. For 20000 (ab doesn't allow more)
concurrent clients about 83000 requests were processed per second. The response consists of
standard header and two chars body.
For a single client I have got about 22000 requests per second.
Another test is for throughput: on the same workstation and 100 concurrent clients
downloading ~3Mb files (and with default 4 KB buffers) I have got: "Transfer rate:
1552710.18 [Kbytes/sec] received". For 10000 clients it's about 1420000 Kbytes/sec.
documentation
The manual is here. Also you can look at HomeServer.scala demo -
browse your home directory.
source code
Is here: tiscaf-0.7.zip.
feedback
Send to me, Andrew Gaydenko, a@gaydenko.com (please, add tiscaf to your subject).
I'm mostly interested in a feedback concerning tricky requests dropping a (reasonably
configured) server down - if you are able to construct such request. Also I'm open for donations.
events (in reverse order)
2012.07.16 v.0.7 is out - just a small fix: Lucas Satabin has found
a bug in multiple request parameters decoding. Lucas, thanks!
2012.01.15 v.0.6 is out - towards arbitrary "dynamics". Among changes and small fixes these ones are
interesting:
- HTalk.req internal object's type is now extracted
to HReqData trait.
-
HApp.resolve takes now this HReqData parameter
instead of HReqHeaderData.
-
Added new HLet's method
def talkExecutor: Option[HLetExecutor] = None where
trait HLetExecutor needs the only method to implement:
def submit(req: HReqData, run: Runnable). This way you have
arbitrary possibilities to execute handler code the way you want - instead of
default execution pool using. Say, you can use some kind of events/subscriptions
model/framework to implement Comet-like client-server interaction (ChatDemo with long-poll
strategy is included into the source archive).
I'd want to emphasize: at all these three cases -
in hApp.resolve implementation,
in hTalk.req using,
and (if you do) in hLet.talkExecutor overriding -
you have the same HReqData information
in you hands - full and ready to use request data.
Also HLet.delegate is eliminated as far as the job hasn't any special meaning
any more after eliminating before method. Just call
anotherLet.act(tk).
2011.11.19 v.0.5 is released. It is a big backend rewrite. Resulted server is simpler to use,
code is more readable. Less synchronization, less mutability. Concurrent requests handling is 2-3 times faster.
Changes:
- Reduced TCP-sessions fragmentation.
- More errors go to HServer.onError.
- HLet.before is eliminated: Scala has traits.
- There is the only executor now, resulting in the only pool size and queue length configuration pair.
- There is the only buffer size in server config now.
- cookieKey and sidKey are moved from
HApp object to HApp trait: now it is possible
to use (or design, or debug) multiple HApps with sessions support (say, manager application
and customer application) simultaneously using different tabs of the same browser.
- Few bugs are fixed (incorrect multiple params handling, incorrect octets handling, probably some others).
- For other minor API (not semantic) changes see the manual or compiler output.
2011.06.09 v.0.4 is released: towards Scala 2.9. Changes:
- Scala 2.9 warnings were eliminated.
- HServer.ports is Set[Int] now (was Seq[Int]).
- HTalk.req.paramKeys is Set[String] now (was Seq[String]).
- HServer.maxPostDataLength is introduced with 65536 as default value.
2010.06.10 v.0.3 is released: towards Scala 2.8. Changes:
- HTracking.uriAndCookie session tracking was removed.
- HApp.sessionTimeoutMinutes default value is 15 now (was 30).
- HApp.maxSessionsCount is introduced with 500 as default value.
- HApp.paramsEncoding is introduced with "UTF-8" as default value.
- HServer.selectorQueueSize is introduced with
Int.MaxValue as default value to limit nio
selector events queue size.
- HTalk.req object has helpers now to access primitives in request
parameters (def asByte(key : String) : Option[Byte], and so on).
- HTalk.ses object extends
scala.collection.mutable.Map[Any,Any] now and has few helpers to
access primitives.
- ResourceLet helper trait is added. It is similar to
FsLet, but is intended to access java resources (say, files
in jars for jars in classpath).
- HTree helper trait is added. If your application has (at least
partly) tree-like structure (uri nodes correspond to request handlers), you can assign handlers
to tree nodes in eyes-friendly manner.
- Fred Janon has pointed me to few English spelling errors in HTTP-protocol related
constants. Fixed now. Fred, thanks!
- cleanup here and there.
2008.11.22 v.0.2.4 is released. Changes:
HReqHeaderData's and HTalk.req's
methods host and port return now
Option[String] instead of String.
Thanks to Will Scullin - he has pointed me there are plenty of simplified http clients
which don't bother about Host-string in request headers.
2008.10.27 v.0.2.3 is released. Changes:
- HServer.stopPort defaults to 8911 - it reduces implementation
code noise at embedded use cases when HServer.startStopListener
may be, say, just empty.
- fixed bug preventing clean overriding of HServer.startStopListener -
thanks to Damián Arregui.
- HReqType has new value PostOctets.
The value is used as fall back POST case when content type differs from
application/x-www-form-urlencoded and multipart/form-data.
At this case concrete post data parsing is delegated to request handler via new
HTalk.req.octets method. Again thanks to Damián Arregui - he
has pointed me at situations with "not too standard" http clients.
2008.10.15 v.0.2.2 is released - again for windows users.
Thanks to Christos KK Loverdos - he has kindly provided .bat scripts to quickly
build-and-try HomeServer.scala demo.
2008.10.15 v.0.2.1 is dedicated to ms windows users. Thanks to
Tim Clendenen - he has pointed to an issue concerning windows file system and tested
a fix.
2008.10.13 v.0.2 is released. Changes:
- a manual was added, and this is a reason to jump to v.0.2.
- shell scripts are slightly modified to be more democratic wrt different Unix-like systems
(my thanks to Manfred Lotz)
- API small changes: time constants now go with unit suffix to be more self-explained
(my thanks to Henry Ware). Also uri method(s) are renamed
to uriPath to reflect reality.
I'm still waiting for further suggestions wrt API stabilization.
2008.10.09 As long as one of the goals of tiscaf publishing is a participating
in adoption and spreading of the Scala programming language, I have decided to lower licensing
restrictions and have republished the application (v.0.1.1) in terms of LGPL.
2008.10.08 tiscaf http server v.0.1 is published in terms of GPL2.