mirror of
https://github.com/matrix-construct/construct
synced 2024-11-29 02:02:38 +01:00
ircd: Add various comments / documentations.
This commit is contained in:
parent
0017a942e2
commit
b4910319e0
3 changed files with 67 additions and 21 deletions
|
@ -48,3 +48,10 @@ standard include group which includes any wrapping to hide SpiderMonkey.
|
|||
- MAPI include group `<ircd/mapi.h>` is the standard header group for modules.
|
||||
This group is an extension to the standard include group but has specific
|
||||
tools for pluggable modules which are not part of the libircd core.
|
||||
|
||||
#### Invocation
|
||||
|
||||
> `libircd` is **not thread-safe**. It does not protect exposed interfaces with
|
||||
locks. Embedders must access `libircd` from a single thread.
|
||||
|
||||
Initialize the library with a call to `ircd::init()`.
|
||||
|
|
|
@ -5,31 +5,36 @@ This directory contains definitions and linkage for `libircd`
|
|||
The purpose of `libircd` is to facilitate the execution of a server which
|
||||
handles requests from end-users. The library hosts a set of pluggable modules
|
||||
which may introduce the actual application features (or the "business logic")
|
||||
of the server. These additional modules are found in the `modules/` directory;
|
||||
of the server.
|
||||
|
||||
##### libircd can be embedded in your application with very minimal overhead.
|
||||
|
||||
Linking to libircd from your executable allows you to customize and extend the
|
||||
functionality of the server and have control over its execution, or, simply use
|
||||
library routines provided by the library without any daemonization.
|
||||
|
||||
##### libircd runs only one server at a time.
|
||||
|
||||
Keeping with the spirit of simplicity of the original architecture, `libircd`
|
||||
continues to be a "singleton" object which uses globals and keeps actual server
|
||||
state in the library itself. In other words, **only one IRC daemon can exist
|
||||
within a process's address space at a time.** Whether or not this was a pitfall
|
||||
of the original design, it has emerged over the decades as a very profitable
|
||||
decision for making IRCd an accessible open source internet project.
|
||||
> The executable linking and invoking `libircd` may be referred to as the
|
||||
"embedding" or just the "executable" interchangably in this documentation.
|
||||
|
||||
##### libircd is single-threaded✝
|
||||
|
||||
This methodology ensures there is an _uninterrupted_, _uncontended_,
|
||||
_predictable_ execution. If there are periods of execution which are
|
||||
computationally intense like parsing, hashing, cryptography, etc: this is
|
||||
absorbed in lieu of thread synchronization and bus contention. Scaling this
|
||||
system is done through running multiple independent instances which
|
||||
synchronize with application logic.
|
||||
The design of `libircd` is fully-asynchronous, single-thread-oriented. No code
|
||||
in the library _blocks_ the process. All operations are conducted on top of
|
||||
a single `boost::asio::io_service` which must be supplied by the executable
|
||||
linking to `libircd`. That `io_service` must be orchestrated by the executable
|
||||
at its discretion; typically the embedder's call to `ios.run()` is the only
|
||||
place the process will _block_.
|
||||
|
||||
> Applications are limited by one or more of the following bounds:
|
||||
- Computing: program is limited by the efficiency of the CPU over time.
|
||||
- Space: program is limited by the space available for its dataset.
|
||||
- I/O: program is limited by external events, disks, and networks.
|
||||
|
||||
`libircd` is dominated by the **I/O bound**. Its design is heavily optimized
|
||||
for this assumption with its single-thread orientation. This methodology
|
||||
ensures there is an _uninterrupted_, _uncontended_, _predictable_ execution
|
||||
which is easy for developers to reason about intuitively with
|
||||
sequential-consistency in a cooperative coroutine model.
|
||||
|
||||
If there are periods of execution which are computationally intense like
|
||||
parsing, hashing, cryptography, etc: this is absorbed in lieu of thread
|
||||
synchronization and bus contention. This system achieves scale through running
|
||||
multiple independent instances which synchronize at the application-logic
|
||||
level.
|
||||
|
||||
✝ However, don't start assuming a truly threadless execution for the entire
|
||||
address space. If there is ever a long-running background computation or a call
|
||||
|
@ -48,6 +53,21 @@ easy to follow.
|
|||
✝ If there are certain cases where we don't want a stack to linger which may
|
||||
jeopardize the c10k'ness of the daemon the asynchronous pattern is still used.
|
||||
|
||||
##### libircd can be embedded in your application with very minimal overhead.
|
||||
|
||||
Linking to libircd from your executable allows you to customize and extend the
|
||||
functionality of the server and have control over its execution, or, simply use
|
||||
library routines provided by the library without any daemonization.
|
||||
|
||||
##### libircd runs only one server at a time.
|
||||
|
||||
Keeping with the spirit of simplicity of the original architecture, `libircd`
|
||||
continues to be a "singleton" object which uses globals and keeps actual server
|
||||
state in the library itself. In other words, **only one IRC daemon can exist
|
||||
within a process's address space at a time.** Whether or not this was a pitfall
|
||||
of the original design, it has emerged over the decades as a very profitable
|
||||
decision for making IRCd an accessible open source internet project.
|
||||
|
||||
##### libircd leverages formal grammars
|
||||
|
||||
We utilize the `boost::spirit` system of parsing and printing through formal grammars,
|
||||
|
|
19
ircd/fs.cc
19
ircd/fs.cc
|
@ -672,6 +672,13 @@ ircd::fs::read(const string_view &path,
|
|||
return read(fd, bufs, opts);
|
||||
}
|
||||
|
||||
/// Read from file descriptor fd into buffers. The number of bytes read into
|
||||
/// the buffers is returned. By default (via read_opts.all) this call will
|
||||
/// loop internally until the buffers are full or EOF. To allow for a partial
|
||||
/// read(), disable read_opts.all. Note that to maintain alignments (i.e when
|
||||
/// direct-io or for special files read_opts.all must be false). By default
|
||||
/// (via read_opts.interruptible) this call can throw if the syscall was
|
||||
/// interrupted before reading any bytes.
|
||||
size_t
|
||||
ircd::fs::read(const fd &fd,
|
||||
const mutable_buffers &bufs,
|
||||
|
@ -700,6 +707,12 @@ ircd::fs::read(const fd &fd,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/// Lowest-level read() call. This call only conducts a single operation
|
||||
/// (no looping) and can return a partial read(). It does have branches
|
||||
/// for various read_opts. The arguments involve `struct ::iovec` which
|
||||
/// we do not expose to the ircd.h API; thus this function is internal to
|
||||
/// ircd::fs. There is no reason to use this function in lieu of the public
|
||||
/// fs::read() suite.
|
||||
size_t
|
||||
ircd::fs::read(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
|
@ -941,6 +954,12 @@ ircd::fs::write(const fd &fd,
|
|||
return off;
|
||||
}
|
||||
|
||||
/// Lowest-level write() call. This call only conducts a single operation
|
||||
/// (no looping) and can return early with a partial write(). It does have
|
||||
/// branches for various write_opts. The arguments involve `struct ::iovec`
|
||||
/// which we do not expose to the ircd.h API; thus this function is internal to
|
||||
/// ircd::fs. There is no reason to use this function in lieu of the public
|
||||
/// fs::read() suite.
|
||||
size_t
|
||||
ircd::fs::write(const fd &fd,
|
||||
const const_iovec_view &iov,
|
||||
|
|
Loading…
Reference in a new issue