diff --git a/README.md b/README.md index 97315f854..0b374fd0f 100644 --- a/README.md +++ b/README.md @@ -2,30 +2,34 @@ **I**nternet **R**elay **C**hat **d**aemon: *Charybdis* -Charybdis is designed to be fast and highly scalable. It is also designed to be community- -developed by volunteer contributors over the internet. This makes Charybdis easy to understand, -modify, audit, and extend. - IRCd is a free and open source server which facilitates real-time communication over the internet. It was started in 1988 by Jarkko Oikarinen in the University of Oulu and eventually -made its way to William Pitcock et al, whom after 2005 developed the project under the alias +made its way to William Pitcock et al, whom after 2005 developed the project under the brand *Charybdis*. In 2014 a protocol was proposed to reinvigorate real-time communication in lieu of growing commercial competition and a lack of innovation from open source alternatives to -compete. This protcol is known as the **Matrix protocol**. +compete. This protocol is known as the **Matrix protocol**. -##### IRCd now implements the Matrix protocol. +**IRCd now implements the Matrix protocol.** # Charybdis/5 -Charybdis Five is the first high performance implementation of **Matrix** written in C++. It remains -true to its roots for being highly scalable, modular and having minimal requirements. Most of the -old code has been rewritten but with the same architecture and spirit of the original. +Charybdis is designed to be fast and highly scalable, and to be community +developed by volunteer contributors over the internet. This mission strives to +make the software easy to understand, modify, audit, and extend. + +Charybdis Five is the first implementation of *Matrix* written in C++. It remains +true to its roots for being highly scalable, modular and having minimal requirements. +Most of the old code has been rewritten but with the same architecture and spirit of +the original. -### Dependencies +## Installation + + +#### Dependencies **Boost** (1.61 or later) - We have replaced libratbox with the well known and actively developed Boost libraries. These are included as a submodule in this repository. @@ -39,9 +43,6 @@ and have furthered the mission of eliminating the need for external "IRC service *Other dependencies:* **OpenSSL**, **zlib**, **snappy** (for rocksdb) -### Installation - - #### Downloading Charybdis `git clone https://github.com/charybdis-ircd/charybdis` @@ -50,7 +51,7 @@ and have furthered the mission of eliminating the need for external "IRC service - Verify you have the latest source tree and **are on the Matrix branch**. -#### Building from git (production) +### Building from git (production) `./autogen.sh` `./configure` @@ -60,11 +61,14 @@ and have furthered the mission of eliminating the need for external "IRC service #### Building from git (DEVELOPER PREVIEW INSTRUCTIONS) +*This is only intended to allow development with dependencies that have not made +their way to mainstream systems yet.* **Not for release.** + The developer preview will install charybdis in a specific directory isolated from the -system. It will not install and avoid using system libraries. Instead it will download -and build the dependencies from the submodules we have pinned here and build them the -way we have configured. Charybdis should be executed using those builds. You may need -to set the `LD_LIBRARY_PATH` to the built libraries. This is not required for release. +system. It will avoid using system libraries by downloading and building the dependencies +from the submodules we have pinned here and build them the way we have configured. You may +need to set the `LD_LIBRARY_PATH` to the built libraries and/or maintain an intact build +directory. `./autogen.sh` `mkdir build` diff --git a/doc/CPP_HOWTO.md b/doc/CPP_HOWTO.md index 4dc210dd3..10e7d2fc1 100644 --- a/doc/CPP_HOWTO.md +++ b/doc/CPP_HOWTO.md @@ -240,5 +240,3 @@ other words, if you have a prototype like `foo(const std::string &message)` you `message` because std::string is common and *what* the string is for is otherwise opaque. OTOH, if you have `foo(const options &, const std::string &message)` one should skip the name for `options &` as it just adds redundant text to the prototype. - - diff --git a/include/ircd/README.md b/include/ircd/README.md index 6b503961f..fef34bcd6 100644 --- a/include/ircd/README.md +++ b/include/ircd/README.md @@ -1,61 +1,60 @@ # IRCd Library +This library can be embedded by developers creating their own server or those +who simply want to use the library of routines it provides. See the section for +`Using 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 introduce the actual application features (or the "business logic") of -the server. These additional modules are found in the `modules/` directory; -see the section for `Developing a module` for more information. This library -can be embedded by developers creating their own server or those who simply -want to use the routines it provides; see the section for `Using libircd`. +which may introduce the actual application features (or the "business logic") +of the server. These additional modules are found in the `modules/` directory; ### Using libircd -`libircd` can be embedded in your application. This 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. -The prototypical embedding of `libircd` is `charybdis` found in the `charybdis/` -directory. +##### libircd can be embedded in your application with very minimal overhead. + +This 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. Including libircd headers will not include any other +headers beyond those in the standard library, with minimal impact on your project's +compile complexity. The prototypical embedding of `libircd` is `charybdis` found in +the `charybdis/` directory. + +##### 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 other words, only one IRC daemon can exist within a process's address -space at any time. This is actually a profitable design decision for making -IRCd easier to understand for contributors. The original version of this library -was created at the dawn of the era of dynamic shared objects and began as an -abstraction of code from the server executable. This was done so that additional -feature modules could be created while all sharing the same maps of routines. +state in the library itself. In other words, **only one IRC daemon can exist +within a process's address space at a time.** This is actually a profitable +design decision for making IRCd easier to understand for contributors. -The library is based around the `boost::asio::io_service` event loop. It is -nominally single threaded and serializes operations on a single asio strand. -In other words, most code is executed on the thread where you call `ios.run()`; -this is referred to as the "main thread." If ios.run() is called on multiple -threads no concurrency will occur. IRCd occasionally uses global and static -variables; the expectation is that these will not be contended outside of the -main thread. The library may spawn additional threads, mostly from 3rd party -libraries and only under daemonization. We don't like this, and try to prevent -it, but it may happen under certain circumstances. These are all dealt with -internally and shouldn't affect the users of the library. +##### libircd is single-threaded✝ + +The library is based around the `boost::asio::io_service` event loop. It is still +an asynchronous event-based system. We process one event at a time; developers must +not block execution. Events are never processed concurrently on different threads✝. + +However, there are some ✝'s here which must be addressed. We have introduced +additional standard threads to libircd with the purpose of "offloading" operations +from some library dependencies that don't cooperate asynchronously. This ensures the +"main thread" running the actual event loop is never blocked in any case. Furthermore, +some 3rd party dependencies like RocksDB (and boost::asio's DNS resolver) may +introduce threads into the address space which they handle privately. + +##### libircd introduces userspace threading + +IRCd presents an interface introducing stackful coroutines, a.k.a. userspace context +switching, or green threads. The library does not use callbacks as the way to break +up execution when waiting for events. Instead, we harken back to the simple old ways +of synchronous programming, where control flow and data are easy to follow. + +##### libircd innovates with formal grammars + +We leverage the boost::spirit system of parsing and printing through formal grammars, +rather than writing our own parsers manually. In addition, we build several tools +on top of such formal devices like a type-safe format string library acting as a +drop-in for ::sprintf(), but accepting objects like std::string without .c_str() +and prevention of outputting unprintable/unwanted characters that may have been +injected into the system somewhere prior. -### Developing a module - -libircd facilitates the development of dynamic shared modules which implement -specific application logic used in the server. - - -### Hacking on libircd - -#### Style - -##### Misc - -* When using a `switch` over an `enum` type, put what would be the `default` case after/outside -of the `switch` unless the situation specifically calls for one. We use -Wswitch so changes to -the enum will provide a good warning to update any `switch`. - -* Prototypes should name their argument variables to make them easier to understand, except if -such a name is redundant because the type carries enough information to make it obvious. In -other words, if you have a prototype like `foo(const std::string &message)` you should name -`message` because std::string is common and *what* the string is for is otherwise opaque. -OTOH, if you have `foo(const options &, const std::string &message)` one should skip the name -for `options &` as it just adds redundant text to the prototype.