47 Commits

Author SHA1 Message Date
Joris Vink
c463ecb3cb Changes to the event loop inside of Kore.
Now anyone can schedule events and get a callback to work as long
as the user data structure that is added for the event begins
with a kore_event data structure.

All event state is now kept in that kore_event structure and renamed
CONN_[READ|WRITE]_POSSIBLE to KORE_EVENT_[READ|WRITE].
2018-10-09 19:34:40 +02:00
Joris Vink
03b927dd64 missing EPOLLET when we reschedule read/write 2018-08-01 12:17:16 +02:00
Joris Vink
ac6fcf8981 deal with sendfile() in newer linux kernels. 2018-07-09 10:00:38 +00:00
Joris Vink
cca269ff5d make sure we use fd_off in linux sendfile properly 2018-06-29 03:10:28 +00:00
Joris Vink
80f5425698 Add filemaps.
A filemap is a way of telling Kore to serve files from a directory
much like a traditional webserver can do.

Kore filemaps only handles files. Kore does not generate directory
indexes or deal with non-regular files.

The way files are sent to a client differs a bit per platform and
build options:

default:
  - mmap() backed file transfer due to TLS.

NOTLS=1
  - sendfile() under FreeBSD, macOS and Linux.
  - mmap() backed file for OpenBSD.

The opened file descriptors/mmap'd regions are cached and reused when
appropriate. If a file is no longer in use it will be closed and evicted
from the cache after 30 seconds.

New API's are available allowing developers to use these facilities via:
  void net_send_fileref(struct connection *, struct kore_fileref *);
  void http_response_fileref(struct http_request *, struct kore_fileref *);

Kore will attempt to match media types based on file extensions. A few
default types are built-in. Others can be added via the new "http_media_type"
configuration directive.
2018-06-28 13:27:44 +02:00
Joris Vink
dd2dff2318 Rework HTTP and worker processes.
The HTTP layer used to make a copy of each incoming header and its
value for a request. Stop doing that and make HTTP headers zero-copy
all across the board.

This change comes with some api function changes, notably the
http_request_header() function which now takes a const char ** rather
than a char ** out pointer.

This commit also constifies several members of http_request, beware.

Additional rework how the worker processes deal with the accept lock.

Before:
	if a worker held the accept lock and it accepted a new connection
	it would release the lock for others and back off for 500ms before
	attempting to grab the lock again.

	This approach worked but under high load this starts becoming obvious.

Now:
	- workers not holding the accept lock and not having any connections
	  will wait less long before returning from kore_platform_event_wait().

	- workers not holding the accept lock will no longer blindly wait
	  an arbitrary amount in kore_platform_event_wait() but will look
	  at how long until the next lock grab is and base their timeout
	  on that.

	- if a worker its next_lock timeout is up and failed to grab the
	  lock it will try again in half the time again.

	- the worker process holding the lock will when releasing the lock
	  double check if it still has space for newer connections, if it does
	  it will keep the lock until it is full. This prevents the lock from
	  bouncing between several non busy worker processes all the time.

Additional fixes:

- Reduce the number of times we check the timeout list, only do it twice
  per second rather then every event tick.
- Fix solo worker count for TLS (we actually hold two processes, not one).
- Make sure we don't accidentally miscalculate the idle time causing new
  connections under heavy load to instantly drop.
- Swap from gettimeofday() to clock_gettime() now that MacOS caught up.
2018-02-14 13:48:49 +01:00
Joris Vink
548348f553 2018 2018-01-20 22:51:06 +01:00
Joris Vink
4ad50caa29 Large changes to the memory subsystem in kore.
- Change pools to use mmap() for allocating regions.
- Change kore_malloc() to use pools for commonly sized objects.
  (split into multiple of 2 buckets, starting at 8 bytes up to 8192).
- Rename kore_mem_free() to kore_free().

The preallocated pools will hold up to 128K of elements per block size.

In case a larger object is to be allocated kore_malloc() will use
malloc() instead.
2016-07-12 13:54:14 +02:00
Joris Vink
82a9e6ef59 Formatting and unbreaking NOHTTP builds. 2016-02-01 20:02:02 +01:00
Stig Telfer
2ac6e7d41d Merge branch 'master' into oneswig 2016-01-24 13:46:38 +00:00
Stig Telfer
18d3cc032d rename *_fini to *_cleanup 2016-01-04 21:40:14 +00:00
Joris Vink
c4b1206ae3 Bump copyright to 2016. 2016-01-04 12:58:51 +01:00
Stig Telfer
0c51d9da53 Add resource management as part of the kore shutdown process. 2015-12-29 19:39:39 +00:00
Joris Vink
d3332d5921 Add kore_platform_schedule_write(). 2015-12-09 21:29:44 +01:00
Joris Vink
77364e49cd Do not call handle if not set, similar to bsd.c. 2015-12-02 21:57:16 +01:00
Joris Vink
961a2e3685 Allow apps to override connection handling.
Setting the handle callback allows your application
to take care of network events for the connection.

Look at the connection state and flags to determine
if read/write is possible and go from there.

See kore_connection_handle() for more details.
2015-12-01 20:55:00 +01:00
Joris Vink
5228fe1cbc Fix typo in configuration option worker_accept_treshold.
There is no backwards comptabile option available.

Fixes #53
2015-05-18 12:20:28 +02:00
Joris Vink
e2ce032b02 Do not treat EPOLLRDHUP as a connection error. 2015-05-15 19:10:23 +02:00
Joris Vink
b869041a14 Introduce new config option worker_accept_treshold
This configuration option limits the maximum number
of connections a worker process can accept() in a single
event loop.

It can be used to more evenly spread out incoming connections
across workers when new connections arrive in a burst.
2015-04-23 10:24:00 +02:00
Joris Vink
4c39ac43fb Properly deal with accept() failing.
In cases where accept() failed Kore would not relinquish the
lock towards other worker processes.

This becomes evident when dealing with a high number of concurrent
connections to the point the fd table gets full. In this scenario
the worker with the full fd table will spin on attempt to accept
newer connections.

As a bonus, Kore now has allows exactly up to worker_max_connections
of connections per worker before no longer attempting to grab the
accept lock.
2015-04-20 15:17:42 +02:00
Joris Vink
097a1166df Improve very heavy load handling.
Introduces two new configuration knobs:
	* socket_backlog (backlog for listen(2))
	* http_request_limit

The second one is the most interesting one.

Before, kore would iterate over all received HTTP requests
in its queue before returning out of http_process().

Under heavy load this queue can cause Kore to spend a considerable
amount of time iterating over said queue. With the http_request_limit,
kore will process at MOST http_request_limit requests before returning
back to the event loop.

This means responses to processed requests are sent out much quicker
and allows kore to handle any other incoming requests more gracefully.
2015-04-09 15:29:44 +02:00
Joris Vink
af865abede Bump copyright to 2015 2015-04-07 13:08:26 +02:00
Joris Vink
67efb9b04a better brackets around some if statements. 2015-01-19 15:31:36 +01:00
Joris Vink
6de0f8568a Rework net, worker and some http internals.
- The net code no longer has a recv_queue, instead reuse same recv buffer.
- Introduce net_recv_reset() to reset the recv buffer when needed.
- Have the workers spread the load better between them by slightly
  delaying their next accept lock and giving them an accept treshold
  so they don't go ahead and keep accepting connections if they end
  up winning the race constantly between the workers.
- The kore_worker_acceptlock_release() is no longer available.

- Prepopulate the HTTP server response header that is added to each
  response in both normal HTTP and SPDY modes.
- The path and host members of http_request are now allocated on the heap.

These changes overall result better performance on a multicore machine,
especially the worker load changes shine through.
2014-10-22 21:16:49 +02:00
Joris Vink
693a07250f bump copyright years 2014-10-14 16:18:23 +02:00
Joris Vink
7771adbec2 Allow applications to create new connections in our event loop. 2014-09-17 08:25:45 +02:00
Joris Vink
c063dd52f6 epoll improvements.
* check for EPOLLRDHUP
* in kore_platform_schedule_read() don't use EPOLLET
2014-08-21 16:33:11 +02:00
Joris Vink
26d4d5d63b Rework the accept lock.
Kore no longer passes the accept lock to the "next in line"
worker but instead all workers will attempt to grab the lock
if they can.

Also remember if we had the lock previous iteration of the
event loop and don't constantly disable/enable the accepting sockets.

Makes Kore scale even better across multiple cpu's.
2014-07-30 15:20:09 +02:00
Joris Vink
478c008c99 Missing parts from last commit 2014-07-28 23:35:12 +02:00
Joris Vink
2c6b5e6b0f Normalize kore_*.h headers 2014-07-03 22:14:46 +02:00
Joris Vink
723c99b65e Move kore_pgsql.h into includes/ directly.
Much like kore_tasks.h
2014-06-30 08:42:18 +02:00
Joris Vink
146a0189ab More work on the background task implementation.
Tasks are now assigned to available threads instead
of a global task list.

You can now pass messages between your page handler
and the created task using the kore_task_channel_*
functions.

Only one task per time can be assigned to a request
but I feel this is probably a bad design choice.

Preferably we'd want to be able to start tasks
regardless of being in a page handler or not,
this not only ads flexibility but seems like
a better choice overall as it opens a lot more
possibilities about how tasks can be used.
2014-06-29 14:15:40 +02:00
Joris Vink
cf700b34f7 Add initial stab at asynchronous background tasks.
More to follow.
2014-06-28 16:17:18 +02:00
Joris Vink
2f044cc7eb Initial stab at entering postgresql contrib code.
Has support for full async pgsql queries. Most of the logic
is hidden behind a KORE_PGSQL() macro allowing you to insert
these pgsql calls in your page handlers without blocking the
kore worker while the query is going off.

There is place for improvement here, and perhaps KORE_PGSQL won't
stay as I feel this might overcomplicate things instead of making
them simpler as I thought it would.
2014-03-30 23:54:35 +02:00
Joris Vink
659e19f92f add IPv6 support and support for multiple listeners. 2013-07-27 20:56:15 +02:00
Joris Vink
29fa49ba83 Add fixed size memory pools and use them throughout Kore. 2013-07-15 11:06:36 +02:00
Joris Vink
f59e94a7b6 Add spdy_session_teardown() which can properly teardown a SPDY session.
Use this throughout the spdy code to propagate session errors (if any) occur.

At the same time fix BSD's missing CONN_WRITE_BLOCK
2013-07-13 19:56:38 +02:00
Joris Vink
c1723f2db5 Clean up header includes, based on a diff from Ewan Higgs via github.
And while we're messing in it, make sure bsd.c compiles again.
2013-07-06 20:55:22 +02:00
Joris Vink
886c3920db sysconf() returns -1 on failure, cpu_count is an unsigned integer, failure would never have been caught.
from cremno via github
2013-07-05 22:17:56 +02:00
Joris Vink
51a9e4db9d Implement SPDY WINDOW_UPDATE and SETTINGS. 2013-07-01 11:30:18 +02:00
Joris Vink
108a0cbc81 remove unneeded blocks of code 2013-06-27 12:37:27 +02:00
Joris Vink
b4a0330a96 - Better spread load between all worker processes.
- Introduce own memory management system on top of malloc to keep track
  of all our allocations and free's. Later we should introduce a pooling
  mechanism for fixed size allocations (http_request comes to mind).
- Introduce ssl_cipher in configuration.

Memory usage is kind of high right now, but it seems its OpenSSL
doing it rather then Kore.
2013-06-27 08:43:07 +02:00
Joris Vink
2fc5233358 Rework the way worker processes give each other the accept lock.
Instead of waiting until one worker is filled up on connections
the workers find the next lowest loaded worker and will hand
over the lock to them instead. This will cause a nicer spread of load.

Instead of running one accept per event loop, we attempt to accept
as many as worker_max_connections allows.

Refactor net sending/recv code a bit.
2013-06-27 00:22:48 +02:00
Joris Vink
0dda6f996f Add a form of synchronization between what worker will be accepting
new connections and which ones will not be notified for it.

Fixes the thundering herd problem, and nicely spreads out load between
all the workers equally. A configuration option (workers_max_connections)
is available to tweak how many connections a worker will have before
giving up the accept lock.

Two ways are added to this commit for access locking:
- Locking via semaphores.
- Locking via GCC's builtin atomic methods.

The default is running with semaphores disabled (OpenBSD cannot do
sem_init() with pshared set to 1, which is required).

If you want to use semaphores add KORE_USE_SEMAPHORES to CFLAGS,
and -lpthread to LDFLAGS in the Makefile.

Other fixes:
- BSD: add a timeout to kevent().
- Merge kore_worker_wait together, linux knows waitpid() as well.
- Send the correct SIGQUIT signal to workers instead of SIGINT.
- Fix kore_time_ms().
- Log fatal worker messages in syslog.
- Refactor code even more.
- Do not free our own kore_worker structure.
2013-06-26 16:37:22 +02:00
Joris Vink
3e5c17b8a3 refactor code quite a bit. 2013-06-26 11:18:32 +02:00
Joris Vink
a1b400c400 Add access logging to Kore. 2013-06-24 09:36:40 +02:00
Joris Vink
25f1ab9865 Add BSD kqueue(2) support. Compile with make bsd (or make linux for linux) 2013-06-17 23:39:17 +02:00