General TODO¶
When possible, TODO items should be documented in the source. Items in this document:
TODO items regarding core architecture
TODO items regarding interface changes
ALSO…: TODO items that should really be in source…
✅ |
⬜ |
❌ |
⬇️ |
🚧 |
done |
not done |
won’t do |
deprioritized |
WIP |
|
|
|
|
|
Contents
Next Up¶
⬜ Add GPL exceptions for OpenSSL + Python (IMO, python API is pretty clearly a “System Interface” anyway, but we’ll make it explicit).
⬜ Generic list/pool/queue types (ala kernel)
🚧 HTTP header compare override
⬜ Provide faster file handling (sendfile or caching)
⬜ WSGI code cleanup / PEP3333 compliance check
⬜ WSGI: don’t user buffered HTTP mode (avoid allocating payload size since it’s read as an iterator).
⬜
EV_EMBED
,ev_realloc
, and faux-slab allocator example⬜ WSGI example needed!
✅ WSGI startup configuration is inflexible (2nd arg can now be an arbitrary python statement).
✅ Cleanup allocators/weak/weakref, etc
✅ Fix ymo_base64_encode memory leak!
✅ Clean up configure.sh build time/number of checks!
✅ UPDATE LICENSE INFO
✅ Gather/Scatter IO
✅ Object model
✅ Write convenience functions for protocol startup (see below)
✅ Docs on public vs private
✅ Build options for development headers
✅ Shift connection header table to hash?
❌ Commit to gcore/apr (neither!)
Tidying¶
❌ Exchanges: why allocate request/response separately? It’s the source of a lot of cache misses (sometimes need disentangled responses + allows request re-use)
✅ We work with lots of strings of known length — make some string utilities and take advantage of that. (WIP!)
🚧 Most
_creates
need an_init
(see needs init) to facilitate static allocation / the next item in this list.⬜ Don’t
void*
+malloc
when an intrusive data structure would do.⬜ Multiple alignment CEIL/FLOOR definitions + assumptions about the relationship between
sizeof()
and alignment⬜ Ditch the bit-fields, just use flags, and skip needing to write a set of rules about when to use which.
TESTS!!!!¶
(✅ doesn’t imply full coverage).
⬜ Facilities for testing custom protocols (WIP!)
- ✅ HTTP unit tests
✅ Header tables
✅ Parser: init, loader, tests
- ✅ HTTP client/server tests
✅ HTTP 1.1 Basics
✅ HTTP 1.0 Basics
✅ Core unit tests
✅ WS unit tests (autobahn)
❌ (MQTT unit tests)
✅ automatic live/integration tests — e.g. HTTP request/response validation against a running server, autobahn, etc.
✅ How to test client/server in CI (GH Actions, atm)? Docker compose.
DOCS¶
⬜ Tidy
c2sphinx
+ make public.❌ Use sphinx plantuml plugin instead of bash. (Nah)
⬜ Consider using sphinx emoji instead of replacements file.
⬜ Stop abusing CSS/poor alabaster and make a proper theme.
✅ HTTP Overview (basic)
⬜ WS Overview
✅ Callbacks and return codes
✅ Core overview
⬜ Tutorials (and/or make info in the guide step-wise, not incidental)
⬜ More comprehensive examples
Packaging¶
✅ Distribute
make dist
output as tar.gz✅ Docker (WSGI runner, example servers)
⬜ Homebrew (WIP!)
⬜ RPM’s? Deb? (…or whatever else is cool and used a lot?…)
Accidental Not-Invented-Here-Syndrome Fixes¶
❓ Switch from
ymo_assert
toUnity
?❓ Make logging more configurable or use a 3rd party lib (zlog, etc)
Configuration¶
- ⬜ Runtime configuration for the following compile-time options:
✅
YMO_SERVER_IDLE_TIMEOUT
(5
)⬜
YMO_SERVER_RECV_BUF_SIZE
(2
)⬜
YMO_HTTP_RECV_BUF_SIZE
(4
)⬜
YMO_HTTP_REQ_WS_SIZE
(4
)⬜
YMO_HTTP_SEND_BUF_SIZE
(4
)⬜
YMO_MQTT_RECV_BUF_SIZE
(6
)⬜
YMO_BUCKET_MAX_IOVEC
(2
)
Usability/Stability¶
✅ WS body buffering (optional)
⬜ HTTP expect handler callback (automatic handling in place), ala upgrade handler.
⬜ clean up includes and include paths!
Utility¶
⬜ HTTP header collision util
⬜ Instrumentation
⬜ Repurpose trie for HTTP routing
Needs Init¶
Status |
Function |
Notes |
---|---|---|
✅ |
|
Done |
✅ |
|
Already done |
⬜ |
|
? |
⬜ |
|
? |
⬜ |
|
? |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
❌ |
|
Not necessary, atm. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
⬇️ |
|
Low priority. |
General¶
✅ Prune logging statements (round 1)
✅ Provide session UUID’s
✅ If
MSG_DONTWAIT
is defined, don’t bother invoking ymo_sock_nonblocking()?✅ Cleanup bucket interface/PROTOCOL TRANSITIONS
⬜ Add restrict where appropriate
- ⬜ There’s a lot of checking for standard symbols in ymo_check_socket_api;
better to check to see if the socket API is SYS V, BSD, or POSIX and then assume accordingly?
Misc¶
❓ WSGI static build + LTO?
Interface¶
⬜ Users should be able to set up their own socket and still use server
❓ Should users be able to manage their own events and just invoke protocols?
⬜ Clean up server/conn/proto cross-contamination + tidy interfaces
❓ (Should more of the connection functions be public?)
✅ Provide bind/listen code
✅ Eliminate two-struct http_request scheme
✅ Clean up compressed header table generation
- ✅ Decouple server and protocols:
✅ Move proto-specific read/write code into proto translation unit
✅ Add changeable proto pointer to session object
✅ Add primary protocol to server object + invoke init
✅ Add protocol destructor
✅ Make protocols run-time constructible by clients
✅ Pluggable handler callbacks for upgrade requests
⬜ Domain/type-specific allocator overrides
Core Architecture¶
✅ Leverage
SO_REUSEPORT
⬜ Add optional multi-threading support to core.
❓ Add optional multi-process support to core? (Probably: no).
Concurrency¶
⬜ HTTP: document EAGAIN behavior and add thread-safe ev_sync requeue util
⬜ Thread pools (✅ for WSGI — hacky, though)
- ⬜ Create utility function to run a function in a thread with automatic
ev_async cb
✅ Decouple ev_loop / IO from python interpretter, CPU-wise
✅ Re-use ymo_queue nodes for data exchange between the two threads to prevent repeated malloc/free
- Pattern:
✅ Configurable number of pre-fork workers
✅ Configurable number of threads per worker
⬜ Configurable number of gevent greenlets per thread
IO Loops/Event System¶
✅ Move per-session timeout management into session.
Non-blocking I/O¶
✅ determine when to use fcntl vs ioctl
✅ non-blocking accept
✅ non-blocking recv
✅ non-blocking send
Memory¶
✅ Add compile-time allocator specification
✅ Allow user to compile without g_slice (e.g. to use malloc/jemalloc, etc)
✅ User-specified allocators (just macros, atm; make
weak
symbols)⬜ Chain-alloc to complement block-alloc
⬜ HTTP make blalloc
ws
a member ofymo_http_exchange
❓ Add ref-counted allocator?
❓ Reference counting for buckets (maybe)
Performance considerations¶
✅ Use prefix-code state machine for HTTP 1.0/1.1 header parsing
✅ Use libbsat for timeout management to avoid fd-by-fd checks
⬜ Clean up struct packing
Stability/Error Handling¶
✅ Check for recv buffer bounds violations on headers
Server Startup¶
✅ bind
✅ accept
✅ listen
✅ startup/shutdown
✅ configuration
✅ logging (home grown for now; 3rd party later)
Libev Callbacks¶
✅ accept_cb
✅ read_cb
- ✅ idle disconnect timeout
✅ Standard HTTP idle disconnect timeout
Socket Writes¶
- ⬜ Send interface:
✅
...send( ymo_bucket_t* )
✅
...send( YMO_BUCKET_FROM_CPY(const char* data, size_t len) )
✅
...send( YMO_BUCKET_FROM_REF(const char* data, size_t len) )
⬜
...send( ymo_bucket_from_file(FILE* fp) )
⬜
...send( ymo_bucket_from_socket(ymo_conn_t* conn) )
✅ WebSocket write
- ✅ Standard HTTP
✅ Header writes
✅ HTTP bodies
TLS¶
✅ TLS support (HACKY WIP POC, FOLKS!)
⬜ No gatter/scather IO for
SSL_write_ex
— buffer multiple small chunks to avoided repeated calls in to libssl + the system.⬜ support/configuration for alternate TLS libs
Python/WSGI¶
✅ Make WSGI server
- ✅ Connection freeing: hold off in loop thread (reference counting) or
provide some cancellation mechanism to python thread
Protocols¶
HTTP 1.0/1.1¶
✅ facilities to handle all standard HTTP 1.0/1.1 headers
✅ HTTP request pipelining
- ✅ don’t serialize response until it’s ready to go out (i.e. there are no
other responses ahead of it in the pipeline); this prevents overwriting
✅ Close session after first non-keep-alive request served
Parsing¶
✅ parse HTTP request line
- ✅ header parse
✅ HTTP 1.0/1.1 differentiation for standard traits:
✅ Chunking
✅ Keep-alive
Body Parsing¶
- ✅ Buffered, fixed-size POST bodies:
✅ Parsing
✅ Callback
- ✅ Un-buffered, fixed-size POST bodies:
✅ Parsing
✅ Callback
- ✅ Buffered, chunked POST bodies:
✅ Parsing
✅ Callback
- ✅ Un-buffered, chunked POST bodies:
✅ Parsing
✅ Callback
HTTP Compression¶
Request/Response Interface¶
✅ Keep-alive
✅ Content-Length
⬜ Content-Encoding
✅ Transfer-Encoding
⬜ Standard Content Negotiation
Error Codes¶
✅ Look for “Expect” header and send HTTP 100 appropriately
- The following all just clip the TCP connection (fix it!):
⬜ Error out with 400 for malformed requests!
⬜ Error out with 413 or 417 for excessive body size!
⬜ Error out with 431 for excessive header content!
❌ Multi-line header values. (Obsoleted).
WebSockets¶
✅ Upgrade
✅ WebSocket read
✅ Write
- ⬜ Extensions
⬜
permessage-deflate
⬜ Implement (or use) a simple SHA1 lib so that WS can work without OpenSSL.
MQTT¶
✅ Basic parsing
⬜ Topic routing through updated libatra/mqrs
⬜ Clean up type names (follow your own rules!)
⬜ Move appropriate flags to ymo_mqtt.h
Source/Build/Link¶
✅ move built-in http handler to separate translation unit
✅ http parser should not touch server internals
✅ session should not touch server internals
✅ create allocator header for customization
✅ leverage source macros to enforce encapsulation
✅ Add “–enable-maintainer-debug” flag for maintainer builds
✅ cleanup superfluous functions
✅ define undefined compiler extensions
✅ stdint.h inttypes.h + correct format strings (mostly done)
⬜ cleanup superfluous includes
⬜ check for the presence of features.h/cdefs.h
C Dialect¶
(Pick one…)
✅ ISO C11 (for now; may restrict to C99 or expand to GNUC)
❌ ISO C89
❌ ISO C99
❌ GNU C89
❌ GNU C99
❌ GNU C11
Stdlib¶
(Pick one…)
✅ Portable Operating System Interface (POSIX)
✅ ISO C11
❌ ISO C89
❌ ISO C99
❌ Single Unix Specifiation (SUS)
❌ X/Open Portability Guide (XPG)
❌ System V Interface Definition (SVID)
❌ Berkley Unix (BSD)
❌ GNUC
❌ Add C++ compatibility
Dependencies¶
✅ configuration for libev
✅ configuration for libbsat
❌ configuration for glib (removed)
✅ configuration for uuid