summaryrefslogtreecommitdiff
path: root/TODO
diff options
context:
space:
mode:
Diffstat (limited to 'TODO')
-rw-r--r--TODO138
1 files changed, 138 insertions, 0 deletions
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..91007e2
--- /dev/null
+++ b/TODO
@@ -0,0 +1,138 @@
+New, simpler design:
+
+There is an 'Engine' which is both Executor and Mainloop. It uses an
+Epoll object to handle the polling. This epoll object does not do any
+locking by itself.
+
+Contexts can be created; they are like jobqueues, except they also
+allow you to add fd's and idles and timeouts. They can do that since
+they have access to the engine. These are completely unlocked; if you
+want to access a context from more than one thread, you must lock them
+yourself. It is guaranteed that only one callback will be active for a
+context at the same time. From within that callback it is then safe to
+remove other callbacks etc. In general such a context can act pretty
+much like one thread.
+
+A web server will consist of a listening context, which will create
+other contexts as necessary and add the fd's to them with the
+appropriate callback. Or maybe just call back with the new fd. I guess
+there should be a generic listener object that will create its own
+context and call back. Then an http module can just create a listener
+and do whatever it wants in response.
+
+One possible problem. The thread that creates a context and adds the
+fd not necessarily the one that will execute the first callback. Can
+these interfere? Maybe the solution is just that the creating thread
+should not do anything with the context after it adds the fd. A
+better idea may be to just have a context_dispatch() function that you
+must call after creating the context. Until this is called, nothing
+the context is not active.
+
+Beginning of this new design is implemented and can be built with
+build2.sh.
+
+
+
+Old design (referenced above)
+
+Highlevel design for a web server:
+
+ - Executor
+ takes callbacks and executes them, possibly in parallell
+ or out of order. The callbacks are likely to be called in
+ a different thread than the one that queued them.
+
+ Should support both push_back() and push_front(). Push_front()
+ is needed to do parallel requests with good latency. If
+ a request can be parallellized, the parallel tasks should
+ be put at the front of the queue.
+
+ - EPoll
+ Simple class that wraps epoll()/poll(). Note: must support
+ oneshot polling and rearming.
+
+ - JobQueue
+ Maintain a queue of jobs, uses executor to execute them
+ in order. Two jobs in the same JobQueue will never run
+ at the same time.
+
+ - Mainloop
+ Uses executor, epoll.
+ - Takes filedescriptors and callbacks. calls
+ back when descriptor is readable/writable/etc.
+ - The callbacks are put on a job queue, which is passed in
+ - Each callback is a oneshot - ie., after calling, the
+ filedescriptor is not polled again until it is rearmed.
+ The mainloop will have a method to rearm filedescriptors.
+ This ensures that the mainloop can start a new poll()
+ whenever it wants without waiting for all the callbacks
+ to finish.
+ - Also takes timeouts that can be canceled. Timeouts also
+ need to be put on a queue.
+
+ Sketch of implementation:
+
+ polljob()
+ {
+ timeout = compute min_timeout ();
+ if (timeout > 0)
+ poll_armed_describtors(timeout);
+ call all timeouts (ie., put them on queues);
+ call all callbacks (ie., put them on queues);
+ schedule (polljob);
+ }
+
+ - MainContext
+
+ - The thing clients will deal with
+
+ - Uses the main loop
+
+ - Filedescriptors
+ maincontext is responsible for rearming the
+ descriptor after the client callback has been
+ called.
+
+ - Timeouts
+
+ - Idle handlers
+
+ - Everything associated with a main context happens
+ serialized - ie., as if only one thread executed it.
+
+ - This means a client structure doesn't need to be locked.
+
+ - Has a get_executor() method so that clients can parallelize
+ if they want to.
+
+ - Current thinking is that if we have main contexts, who
+ really needs a main loop? The only thing you could do
+ with it is to pass it to main contexts.
+
+ OTOH that's true of several of the objects here.
+ see notes at top of maincontext.c
+
+ - Worth noting that stuff that has to be passed in to
+ create a client object must be available to the
+ listener callback. But see http_server.c for an example
+
+ - Err, the epoll in itself is not enough for maincontext,
+ since it needs to be shared between maincontexts. Ie.,
+ who would call epoll_wait(). We do really need a main
+ loop that will call back.
+
+ - Listener
+ Listens on a port. Calls back with a file descriptor when
+ someone connects.
+
+ - Connection
+ initialized with a MainContext and a filedescriptor.
+ Creates events when something happens
+
+ - Http:
+ Has a Connection
+ parses http, emits events such as
+ "get hostname pagename query"
+ "post etc etc etc"
+
+ - ContentProvider