Felix Palmen
2023-06-09 18:56:18 UTC
Announing my new project: poser.
# WWW
https://zirias.github.io/poser/
# License
BSD 2-clause
# Description
This is a simple no-dependencies framework for implementing your typical
(networking) service in C. It's designed to only use POSIX APIs, so it
should be portable without platform-specific code to any OS that
conforms to POSIX.
It optionally offers TLS, in which case OpenSSL or some API-compatible
library like LibreSSL is needed.
# Design
Poser works fully event-driven and async. It uses async/non-blocking
POSIX APIs where available, and simulates async behavior using a
threadpool when needed.
The main event loop is built around pselect(), which means there's a
hard scalability limit. Although the alternative in POSIX, ppoll(),
wouldn't have this hard limit, it IMHO wouldn't be a huge gain, as
ppoll() needs to copy more data on each call and therefore might perform
even worse. In practice, it just won't perform well for more than around
100 concurrent connections, so if you need this, better use libraries
like e.g. libuv instead.
The API is fully object-oriented and designed for stability, so new
features are unlikely to break API or even ABI. All public type names,
functions and even enum members are prefixed with a (short) "namespace"
to avoid clashes with consumer code or other libraries.
# Why?
This project kind of "happened". When I had the need to write my own
services for some specific use cases, I didn't find any library doing
exactly what I want, so I instead implemented everything myself ... and
a lot of generic code was copy&pasted from one project to the next.
"Backporting" improvements in a new project to an older one became a
real hassle, so I finally decided to pull all the generic code out into
a new library/framework project.
# Features
Currently, there's just one library, libposercore. It offers
* Generic daemonizing code, correctly handling a pidfile
* A simple event-handling mechanism based on direct calls
* A simple logging mechanism with configurable writers
* A main service loop around pselect(), also handling typical signals
* A threadpool to schedule jobs on
* Abstractions for TCP or local Unix domain socket connections, servers
and clients
* Optional TLS support
* Several utility classes and functions
# Dependencies
Well, I said "no-dependencies" and that's true for runtime when built
without TLS support. Still:
* [build] gcc or clang supporting C11
* [build] GNU make
* [build] doxygen to build reference API docs
* [build/run] OpenSSL or compatible, when built WITH_TLS=1 (default)
# Roadmap
Short term: Currently working on some abstractions to describe a
structure for configuration. This should provide a single source of
truth, be able to parse from different sources (like, commandline
arguments and/or a config file), be able to auto-generate usage and
help output as well as a sample config file. Kind of likely to be
completed.
Long term: Add more specialized libs. Currently thinking of a
"libposerweb" implementing HTTP (server/client) and maybe offering some
helper stuff for HTML/JSON/... Also, there might be a "libposerirc" some
day implementing the IRC protocol. Likeliness of realization: we will
see.
# Final words
Purpose of this post is both to actually announce this project, hoping
someone might have some use for it, and of course, to collect feedback
if you want, thanks!
Cheers, Felix
# WWW
https://zirias.github.io/poser/
# License
BSD 2-clause
# Description
This is a simple no-dependencies framework for implementing your typical
(networking) service in C. It's designed to only use POSIX APIs, so it
should be portable without platform-specific code to any OS that
conforms to POSIX.
It optionally offers TLS, in which case OpenSSL or some API-compatible
library like LibreSSL is needed.
# Design
Poser works fully event-driven and async. It uses async/non-blocking
POSIX APIs where available, and simulates async behavior using a
threadpool when needed.
The main event loop is built around pselect(), which means there's a
hard scalability limit. Although the alternative in POSIX, ppoll(),
wouldn't have this hard limit, it IMHO wouldn't be a huge gain, as
ppoll() needs to copy more data on each call and therefore might perform
even worse. In practice, it just won't perform well for more than around
100 concurrent connections, so if you need this, better use libraries
like e.g. libuv instead.
The API is fully object-oriented and designed for stability, so new
features are unlikely to break API or even ABI. All public type names,
functions and even enum members are prefixed with a (short) "namespace"
to avoid clashes with consumer code or other libraries.
# Why?
This project kind of "happened". When I had the need to write my own
services for some specific use cases, I didn't find any library doing
exactly what I want, so I instead implemented everything myself ... and
a lot of generic code was copy&pasted from one project to the next.
"Backporting" improvements in a new project to an older one became a
real hassle, so I finally decided to pull all the generic code out into
a new library/framework project.
# Features
Currently, there's just one library, libposercore. It offers
* Generic daemonizing code, correctly handling a pidfile
* A simple event-handling mechanism based on direct calls
* A simple logging mechanism with configurable writers
* A main service loop around pselect(), also handling typical signals
* A threadpool to schedule jobs on
* Abstractions for TCP or local Unix domain socket connections, servers
and clients
* Optional TLS support
* Several utility classes and functions
# Dependencies
Well, I said "no-dependencies" and that's true for runtime when built
without TLS support. Still:
* [build] gcc or clang supporting C11
* [build] GNU make
* [build] doxygen to build reference API docs
* [build/run] OpenSSL or compatible, when built WITH_TLS=1 (default)
# Roadmap
Short term: Currently working on some abstractions to describe a
structure for configuration. This should provide a single source of
truth, be able to parse from different sources (like, commandline
arguments and/or a config file), be able to auto-generate usage and
help output as well as a sample config file. Kind of likely to be
completed.
Long term: Add more specialized libs. Currently thinking of a
"libposerweb" implementing HTTP (server/client) and maybe offering some
helper stuff for HTML/JSON/... Also, there might be a "libposerirc" some
day implementing the IRC protocol. Likeliness of realization: we will
see.
# Final words
Purpose of this post is both to actually announce this project, hoping
someone might have some use for it, and of course, to collect feedback
if you want, thanks!
Cheers, Felix
--
Dipl.-Inform. Felix Palmen <***@palmen-it.de> ,.//..........
{web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de
{pgp public key} http://palmen-it.de/pub.txt // """""""""""
{pgp fingerprint} 6936 13D5 5BBF 4837 B212 3ACC 54AD E006 9879 F231
Dipl.-Inform. Felix Palmen <***@palmen-it.de> ,.//..........
{web} http://palmen-it.de {jabber} [see email] ,//palmen-it.de
{pgp public key} http://palmen-it.de/pub.txt // """""""""""
{pgp fingerprint} 6936 13D5 5BBF 4837 B212 3ACC 54AD E006 9879 F231