Skip to content

Commit

Permalink
WIP: Add new custom event loop for I/O layer
Browse files Browse the repository at this point in the history
Introduce ev.h and ev.c, establishing the
foundation for the new custom event loop,
`pgagroal_ev`.

Replace previous dependencies on libev with the
custom event loop.

Implement support for io_uring with a fallback to
epoll if io_uring is unavailable.

Add kqueue support.
  • Loading branch information
decarv committed Sep 24, 2024
1 parent 40acff6 commit d5d6680
Show file tree
Hide file tree
Showing 37 changed files with 3,042 additions and 589 deletions.
4 changes: 2 additions & 2 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ What is the version of pgagroal ?

What is the version of PostgreSQL ?

**libev**
**liburing**

What is the version of libev ?
What is the version of liburing ?

**OpenSSL**

Expand Down
4 changes: 4 additions & 0 deletions .github/config/pg_hba.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
local all all trust
host all all all trust
local replication all peer
host replication all all trust
319 changes: 203 additions & 116 deletions .github/workflows/ci.yml

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@ if(NOT COMPILER_SUPPORTS_C17)
message(FATAL_ERROR "The compiler ${CMAKE_C_COMPILER} has no C17 support. Please use a different C compiler.")
endif()

find_package(Libev 4.11)
if (LIBEV_FOUND)
message(STATUS "libev found")
else ()
message(FATAL_ERROR "libev needed")
find_package(Liburing 2.5)
if (LIBURING_FOUND)
message(STATUS "liburing found")
else()
message(STATUS "liburing NOT found")
endif()

find_package(OpenSSL)
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Don't forget to indicate your pgagroal version.
You can use the follow command, if you are using a [Fedora](https://getfedora.org/) based platform:

```
dnf install git gcc cmake make libev libev-devel openssl openssl-devel systemd systemd-devel python3-docutils
dnf install git gcc cmake make openssl openssl-devel systemd systemd-devel python3-docutils liburing liburing-devel
```

in order to get the necessary dependencies.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ See [Performance](./doc/PERFORMANCE.md) for a performance run.

* Process model
* Shared memory model across processes
* [libev](http://software.schmorp.de/pkg/libev.html) for fast network interactions
* [liburing](https://github.com/axboe/liburing) for fast network interactions
* [Atomic operations](https://en.cppreference.com/w/c/atomic) are used to keep track of state
* The [PostgreSQL](https://www.postgresql.org) native protocol
[v3](https://www.postgresql.org/docs/11/protocol-message-formats.html) for its communication
Expand Down Expand Up @@ -64,7 +64,7 @@ See [Architecture](./doc/ARCHITECTURE.md) for the architecture of [**pgagroal**]
* [gcc 8+](https://gcc.gnu.org) (C17)
* [cmake](https://cmake.org)
* [make](https://www.gnu.org/software/make/)
* [libev](http://software.schmorp.de/pkg/libev.html)
* [liburing](https://github.com/axboe/liburing)
* [OpenSSL](http://www.openssl.org/)
* [systemd](https://www.freedesktop.org/wiki/Software/systemd/)
* [rst2man](https://docutils.sourceforge.io/)
Expand All @@ -76,12 +76,12 @@ can be installed via `dnf(8)` as follows:

```sh
dnf install git gcc cmake make \
libev libev-devel \
openssl openssl-devel \
systemd systemd-devel \
python3-docutils \
libatomic \
cjson cjson-devel
cjson cjson-devel \
liburing
```

Please note that, on Rocky Linux, in order to install the `python3-docutils`
Expand Down
38 changes: 0 additions & 38 deletions cmake/FindLibev.cmake

This file was deleted.

18 changes: 18 additions & 0 deletions cmake/FindLiburing.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# - Try to find liburing
# Once done this will define
# LIBURING_FOUND - System has liburing
# LIBURING_LIBRARY - The library needed to use liburing

FIND_LIBRARY(LIBURING_LIBRARY NAMES liburing liburing.a liburing.so liburing.so.2
HINTS
/usr/lib64
/usr/lib
/lib64
/lib
)

IF (LIBURING_LIBRARY)
SET(LIBURING_FOUND TRUE)
ELSE ()
SET(LIBURING_FOUND FALSE)
ENDIF ()
15 changes: 10 additions & 5 deletions doc/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,15 @@ AuthenticationSASLFinal and AuthenticationOk. The SSLRequest message is supporte

The remote management interface is defined in [remote.h](../src/include/remote.h) ([remote.c](../src/libpgagroal/remote.c)).

## libev usage
## I/O layer

[libev](http://software.schmorp.de/pkg/libev.html) is used to handle network interactions, which is "activated"
upon an `EV_READ` event.
Starting from version 2.0.0, the I/O layer interface is primarily defined in [ev.h](../src/include/ev.h)
(and implemented in [ev.c](../src/libpgagroal/ev.c)).

These files contain the definition and implementation of the event loop for the three supported backends:
`io_uring`, `epoll`, and `kqueue`.

[liburing](https://github.com/axboe/liburing) was used for setup and usage io_uring instances.

Each process has its own event loop, such that the process only gets notified when data related only to that process
is ready. The main loop handles the system wide "services" such as idle timeout checks and so on.
Expand Down Expand Up @@ -147,7 +152,7 @@ The functions `start`, `client`, `server` and `stop` has access to the following
```C
struct worker_io
{
struct ev_io io; /* The libev base type */
struct ev_io io; /* The base type for io operations */
int client_fd; /* The client descriptor */
int server_fd; /* The server descriptor */
int slot; /* The slot */
Expand Down Expand Up @@ -235,7 +240,7 @@ The `SIGHUP` signal will trigger a reload of the configuration.
However, some configuration settings requires a full restart of [**pgagroal**](https://github.com/agroal/pgagroal) in order to take effect. These are

* `hugepage`
* `libev`
* `ev_backend`
* `log_path`
* `log_type`
* `max_connections`
Expand Down
2 changes: 1 addition & 1 deletion doc/CONFIGURATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ The available keys and their accepted values are reported in the table below.
| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal or root. |
| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise. |
| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal or root. |
| libev | `auto` | String | No | Select the [libev](http://software.schmorp.de/pkg/libev.html) backend to use. Valid options: `auto`, `select`, `poll`, `epoll`, `iouring`, `devpoll` and `port` |
| ev_backend | `epoll` | String | No | Select the event handling backend to use. Valid options: `io_uring`, `epoll`, and `kqueue` |
| buffer_size | 65535 | Int | No | The network buffer size (`SO_RCVBUF` and `SO_SNDBUF`) |
| keep_alive | on | Bool | No | Have `SO_KEEPALIVE` on sockets |
| nodelay | on | Bool | No | Have `TCP_NODELAY` on sockets |
Expand Down
2 changes: 1 addition & 1 deletion doc/DEVELOPERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ dnf install postgresql-server
#### Basic dependencies

``` sh
dnf install git gcc cmake make libev libev-devel openssl openssl-devel systemd systemd-devel python3-docutils libatomic cjson cjson-devel
dnf install git gcc cmake make openssl openssl-devel systemd systemd-devel python3-docutils libatomic cjson cjson-devel liburing
```

#### Generate user and developer guide
Expand Down
2 changes: 2 additions & 0 deletions doc/etc/pgagroal.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
host = localhost
port = 2345

ev_backend =

log_type = console
log_level = info
log_path =
Expand Down
4 changes: 2 additions & 2 deletions doc/man/pgagroal.conf.5.rst
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ tls_key_file
tls_ca_file
Certificate Authority (CA) file for TLS. Changes require restart in the server section.

libev
The libev backend to use. Valid options: auto, select, poll, epoll, iouring, devpoll and port. Default is auto
ev_backend
The event handling backend to use. Valid options: io_uring, epoll, and kqueue. Default is epoll

buffer_size
The network buffer size (SO_RCVBUF and SO_SNDBUF). Default is 65535
Expand Down
8 changes: 4 additions & 4 deletions doc/manual/02-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,19 +54,19 @@ We recommend using Fedora to test and run [**pgagroal**][pgagroal], but other Li
* [gcc 8+](https://gcc.gnu.org) (C17)
* [cmake](https://cmake.org)
* [make](https://www.gnu.org/software/make/)
* [libev](http://software.schmorp.de/pkg/libev.html)
* [OpenSSL](http://www.openssl.org/)
* [systemd](https://www.freedesktop.org/wiki/Software/systemd/)
* [rst2man](https://docutils.sourceforge.io/)
* [libatomic](https://gcc.gnu.org/wiki/Atomic)
* [cJSON](https://github.com/DaveGamble/cJSON)

```sh
dnf install git gcc cmake make libev libev-devel \
dnf install git gcc cmake make \
openssl openssl-devel \
systemd systemd-devel \
python3-docutils libatomic \
cjson cjson-devel
cjson cjson-devel \
liburing
```

Alternative [clang 8+](https://clang.llvm.org/) can be used.
Expand Down Expand Up @@ -120,7 +120,7 @@ On FreeBSD, `pkg` is used instead of `dnf` or `yum`.
Use `pkg install <package name>` to install the following packages

``` sh
git gcc cmake libev openssl libssh py39-docutils libcjson
git gcc cmake openssl libssh py39-docutils libcjson
```

### Build
Expand Down
2 changes: 1 addition & 1 deletion doc/manual/99-references.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
[gcc]: https://gcc.gnu.org
[cmake]: https://cmake.org
[make]: https://www.gnu.org/software/make/
[libev]: http://software.schmorp.de/pkg/libev.html
[liburing]: https://github.com/axboe/liburing
[openssl]: http://www.openssl.org/
[systemd]: https://www.freedesktop.org/wiki/Software/systemd/
[rst2man]: https://docutils.sourceforge.io/
Expand Down
14 changes: 9 additions & 5 deletions doc/manual/dev-02-architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,15 @@ AuthenticationSASLFinal and AuthenticationOk. The SSLRequest message is supporte

The remote management interface is defined in [remote.h](../src/include/remote.h) ([remote.c](../src/libpgagroal/remote.c)).

## libev usage
## I/O Layer

[libev](http://software.schmorp.de/pkg/libev.html) is used to handle network interactions, which is "activated"
upon an `EV_READ` event.
Starting from version 2.0.0, the I/O layer interface is primarily defined in [ev.h](../src/include/ev.h)
(and implemented in [ev.c](../src/libpgagroal/ev.c)).

These files contain the definition and implementation of the event loop for the three supported backends:
`io_uring`, `epoll`, and `kqueue`.

[liburing](https://github.com/axboe/liburing) was used for setup and usage io_uring instances.

Each process has its own event loop, such that the process only gets notified when data related only to that process
is ready. The main loop handles the system wide "services" such as idle timeout checks and so on.
Expand Down Expand Up @@ -149,7 +154,7 @@ The functions `start`, `client`, `server` and `stop` has access to the following
```C
struct worker_io
{
struct ev_io io; /* The libev base type */
struct ev_io io; /* The base type for io operations */
int client_fd; /* The client descriptor */
int server_fd; /* The server descriptor */
int slot; /* The slot */
Expand Down Expand Up @@ -237,7 +242,6 @@ The `SIGHUP` signal will trigger a reload of the configuration.
However, some configuration settings requires a full restart of [**pgagroal**](https://github.com/agroal/pgagroal) in order to take effect. These are

* `hugepage`
* `libev`
* `log_path`
* `log_type`
* `max_connections`
Expand Down
2 changes: 1 addition & 1 deletion doc/manual/user-02-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ The available keys and their accepted values are reported in the table below.
| tls_cert_file | | String | No | Certificate file for TLS. This file must be owned by either the user running pgagroal or root. |
| tls_key_file | | String | No | Private key file for TLS. This file must be owned by either the user running pgagroal or root. Additionally permissions must be at least `0640` when owned by root or `0600` otherwise. |
| tls_ca_file | | String | No | Certificate Authority (CA) file for TLS. This file must be owned by either the user running pgagroal or root. |
| libev | `auto` | String | No | Select the [libev](http://software.schmorp.de/pkg/libev.html) backend to use. Valid options: `auto`, `select`, `poll`, `epoll`, `iouring`, `devpoll` and `port` |
| ev_backend | `epoll` | String | No | Select the event handling backend to use. Valid options: `io_uring`, `epoll`, and `kqueue` |
| buffer_size | 65535 | Int | No | The network buffer size (`SO_RCVBUF` and `SO_SNDBUF`) |
| keep_alive | on | Bool | No | Have `SO_KEEPALIVE` on sockets |
| nodelay | on | Bool | No | Have `TCP_NODELAY` on sockets |
Expand Down
4 changes: 2 additions & 2 deletions pgagroal.spec
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ URL: https://github.com/agroal/pgagroal
Source0: https://github.com/agroal/pgagroal/archive/%{version}.tar.gz

BuildRequires: gcc cmake make python3-docutils
BuildRequires: libev libev-devel openssl openssl-devel systemd systemd-devel libatomic cjson cjson-devel
Requires: libev openssl systemd libatomic cjson
BuildRequires: liburing liburing-devel openssl openssl-devel systemd systemd-devel libatomic cjson cjson-devel
Requires: openssl systemd libatomic cjson

%description
pgagroal is a high-performance connection pool for PostgreSQL.
Expand Down
20 changes: 14 additions & 6 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
#
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${LIBEV_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIR}
${SYSTEMD_INCLUDE_DIRS}
${CJSON_INCLUDE_DIRS}
Expand All @@ -29,14 +28,24 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
# Library directories
#
link_libraries(
${LIBEV_LIBRARIES}
${OPENSSL_CRYPTO_LIBRARY}
${OPENSSL_SSL_LIBRARY}
${SYSTEMD_LIBRARIES}
${LIBATOMIC_LIBRARY}
${CJSON_LIBRARIES}
)

#
# Event library backend
#
if (LIBURING_FOUND)
add_compile_options(-DHAVE_URING=1)
include_directories(${LIBURING_INCLUDE_DIRS})
link_libraries(${LIBURING_LIBRARY})
endif()

add_compile_options(-DHAVE_EPOLL=1)

set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
find_program(HOMEBREW_EXECUTABLE brew)
Expand Down Expand Up @@ -69,7 +78,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
#
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${LIBEV_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${CJSON_INCLUDE_DIRS}
)
Expand All @@ -78,7 +86,6 @@ elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
# Library directories
#
link_libraries(
${LIBEV_LIBRARIES}
${OPENSSL_LIBRARIES}
${CJSON_LIBRARIES}
)
Expand All @@ -100,16 +107,16 @@ else()
#
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/include
${LIBEV_INCLUDE_DIRS}
${OPENSSL_INCLUDE_DIRS}
${CJSON_INCLUDE_DIRS}
)

add_compile_options(-DHAVE_KQUEUE=1)

#
# Library directories
#
link_libraries(
${LIBEV_LIBRARIES}
${OPENSSL_LIBRARIES}
${CJSON_LIBRARIES}
)
Expand Down Expand Up @@ -210,6 +217,7 @@ if (CMAKE_BUILD_TYPE MATCHES Debug)
if (HAS_NO_OMIT_FRAME_POINTER)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer")
endif()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} -g")
endif()

if (CMAKE_BUILD_TYPE MATCHES Release OR CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
Expand Down
Loading

0 comments on commit d5d6680

Please sign in to comment.