Commit Graph

52 Commits

Author SHA1 Message Date
Joris Vink d0d0bdeb4f Improve pgsql support.
- Add kore_pgsql_query_param_fields() which allows you to pass in the
  arrays for values, lengths and formats yourself.

- Add kore_pgsql_column_binary() which will return 1 if the given column
  index contains a binary result or 0 if it contains a text result.

- Change the query call in req.pgsql() for Python to always use the
  parameterized queries.

This adds the 'params' and 'binary' keywords to the req.pgsql method.

Eg:
	result = await req.pgsql("db", "INSERT INTO foo (field) VALUES($1"),
	    params=["this is my value"])
2019-04-25 23:13:13 +02:00
Joris Vink bf1e8e5ffb bump copyright to 2019 2019-02-22 16:57:28 +01:00
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 7db3e4d946 fix compare match on db name.
from Kevin Lam via patches@
2018-09-19 07:18:46 +02:00
Joris Vink 5b3cee3428 Use a synchronous query to issue a ROLLBACK. 2018-07-28 22:28:19 +02:00
Joris Vink 27d1746940 Consume all notifications on a connection. 2018-07-18 11:40:59 +02:00
Joris Vink 2e321f14de Add KORE_PGSQL_STATE_NOTIFY.
Issue a LISTEN channel on a kore_pgsql, bind a callback to it and you
will get called with pgsql->state being KORE_PGSQL_STATE_NOTIFY.
2018-07-18 11:38:17 +02:00
Joris Vink 4d9346681a shuffle around pgsql_queue_count. 2018-02-14 13:59:23 +01: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 f348feef82 Add pgsql_queue_limit configuration option.
Limits the number of queued asynchronous queries kore will allow
before starting to return errors for KORE_PGSQL_ASYNC setups.

By default set to 1000.

Avoids uncontrolled growth of the pgsql_queue_wait pool.
2018-02-13 13:21:27 +01:00
Joris Vink 548348f553 2018 2018-01-20 22:51:06 +01:00
Joris Vink 4893a030a6 small pgsql fixes.
- make sure conn_count per pgsqldb structure is initialized to 0.
- allow pgsql_conn_max to be 0, meaning just create a new connection
  if none was free.
2017-08-21 14:25:09 +02:00
Joris Vink 8215277483 small pgsql fix.
if we fail at rolling back an in-error transaction on a connection
just remove that connection and go back to rescanning rather then
returning an error to the caller, there may be more functional
connections in the pipeline.
2017-07-13 11:02:41 +02:00
Joris Vink 3cea669a2c call pgsql_conn_cleanup() in case of an error in rollback. 2017-07-11 15:19:44 +02:00
Joris Vink 7f1a9b8092 Several postgresql improvements.
- Make pgsql_conn_count count per database rather then globally.
  This means you now define the number of clients *per* database registered
  rather then the number of clients in total of all databases.

- In case a connection is in failed transaction state Kore will now
  automatically rollback the transaction before placing that connection
  back in the connection pool.
2017-07-11 15:11:13 +02:00
Joris Vink a3ed3bf7eb Convert pgsql-sync example after pgsql changes.
Only check if we bound something if we're asynchronous.
2017-03-24 13:00:05 +01:00
Joris Vink 59f7e85f45 Decouple pgsql from the http layer.
When the pgsql layer was introduced it was tightly coupled with the
http layer in order to make async work fluently.

The time has come to split these up and follow the same method we
used for tasks, allowing either http requests to be tied to a pgsql
data structure or a simple callback function.

This also reworks the internal queueing of pgsql requests until
connections to the db are available again.

The following API functions were changes:
	- kore_pgsql_query_init() -> kore_pgsql_setup()
		no longer takes an http_request parameter.
	- NEW kore_pgsql_init()
		must be called before operating on an kore_pgsql structure.
	- NEW kore_pgsql_bind_request()
		binds an http_request to a kore_pgsql data structure.
	- NEW kore_pgsql_bind_callback()
		binds a callback to a kore_pgsql data structure.

With all of this you can now build kore with PGSQL=1 NOHTTP=1.

The pgsql/ example has been updated to reflect these changes and
new features.
2017-03-24 12:53:07 +01:00
Joris Vink b8c6cddc3d Revert "TAILQ_FOREACH_SAFE() exists so use it."
Because some asshole distributions claim to have a sane queue.h
implementation while they do not.
2017-02-07 22:44:20 +01:00
Joris Vink 0ea911140e TAILQ_FOREACH_SAFE() exists so use it. 2017-02-07 22:35:09 +01:00
Joris Vink c25c1c5281 pgsql: don't do a PQcancel() if it's not needed. 2017-02-06 20:01:16 +01:00
Joris Vink de7a6d4855 pgsql improvements.
- adds new cleanup function that workers will call.
- adds kore_pgsql_nfields() to return number of fields in result.
- add kore_pgsql_fieldname() to return name of a given field.

This commit also changes the behaviour of pgsql_conn_release() in
that it will now cancel the active query before releasing the connection.

This makes sure that if long running queries are active they are hopefully
cancelled if an http request is removed while such queries are still running.
2017-02-06 11:40:33 +01:00
Joris Vink 1ecb777d41 only remove the pgsql if it was scheduled.
fixes #172.
2017-01-29 10:34:53 +01:00
Joris Vink 10929189a0 make sure we can call pgsql_conn_cleanup() properly. 2017-01-10 15:29:03 +01:00
Joris Vink 4f9044c6e0 fix count in kore_pgsql_query_params().
should fix #159.
2016-12-27 09:10:31 +01:00
Tobias Kortkamp 7eced6f035 Fix #153 (#155)
Compiling with Clang 3.9 on FreeBSD raises the following error (see [1]):
```
src/pgsql.c:222:17: error: passing an object that undergoes default argument promotion to 'va_start'
      has undefined behavior [-Werror,-Wvarargs]
        va_start(args, count);
                       ^
src/pgsql.c:217:45: note: parameter of type 'u_int8_t' (aka 'unsigned char') is declared here
    const char *query, int result, u_int8_t count, ...)
```
More information about this warning can be found on [2].

To solve this we can change the type of `count` to `int` in
`kore_pgsql_query_params()` and `kore_pgsql_v_query_params()`. This
also matches the signatures of both `PQexecParams()` [3] and
`PQsendQueryParams()` [4].

[1] https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214639
[2] https://www.securecoding.cert.org/confluence/display/cplusplus/EXP58-CPP.+Pass+an+object+of+the+correct+type+to+va_start
[3] https://www.postgresql.org/docs/9.2/static/libpq-exec.html
[4] https://www.postgresql.org/docs/9.2/static/libpq-async.html
2016-11-19 12:56:51 +01:00
Tobias Kortkamp c071d64bdd Fix #144. Always initialize va_list in kore_pgsql_query_params. (#146) 2016-09-05 16:22:46 +02: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
Raphaël Monrouzeau 159de3960d Added new function kore_pgsql_v_query_params().
Same as kore_pgsql_query_params but takes a va_list as last parameter
(non-v version takes a variable list of parameters).

Lets people write easier to call wrappers around the query calls. I use
it in a wrapper that takes next states (error, current, continue) as
arguments in a handler with multiple async queries.
2016-06-07 13:12:31 +02:00
Joris Vink 3c9d2d5948 missing va_end() in kore_pgsql_query_params().
from @fahlgren.
2016-05-16 09:25:37 +02:00
Joris Vink c4b1206ae3 Bump copyright to 2016. 2016-01-04 12:58:51 +01:00
Joris Vink a281fd5713 Introduce synchronous pgsql queries.
Semantics for using pgsql API have changed quite heavily
with this commit. See the examples for more information.

Based on Github issue #95 by PauloMelo (paulo.melo@vintageform.pt)
with several modifications by me.
2016-01-04 11:12:43 +01:00
Joris Vink 2b2e765fe6 Allow 0 parameters for kore_pgsql_query_params() 2014-10-12 01:17:35 +02:00
Joris Vink a603b77e24 Add PUT/DELETE/HEAD methods (finally).
This commit renames certain POST centric variable and configuration
naming to the correct HTTP body stuff.

API changes include http_postbody_text() and http_postbody_bytes() to
have become http_body_text() and http_body_bytes().

The developer is still responsible for validating the method their
page handler is called with. Hopefully this becomes a configuration
option soon enough.
2014-10-08 11:03:14 +02:00
Joris Vink e1be630b84 Add kore_pgsql_getlength() which will return length of a column. 2014-09-28 23:03:49 +02:00
Joris Vink 3b09683f5c Add kore_pgsql_query_params().
This function uses PQsendQueryParams() instead of the normal PQsendQuery()
allowing you to pass binary data in a cleaner fashion.

A basic call would look something like:

char *mydata = "Hello";
size_t mydata_len = strlen(mydata);

kore_pgsql_query_params(&pgsql, req,
    "INSERT INTO foo VALUES($1::text)", KORE_PGSQL_FORMAT_TEXT, 1
    mydata, mydata_len, KORE_PGSQL_FORMAT_TEXT);

kore_pgsql_query_params() is variadic, allowing you to pass any
count of parameters where each parameter has the following:
	data pointer, data length, type of parameter.
2014-09-28 21:39:16 +02:00
Joris Vink e3417dea16 Remove the pgsql simple layer again.
I rather keep the old idioms instead of adding more complex things
on top of the async ones. Especially since the simple layer would
interfear with existing http state machines from your handler.
2014-09-19 15:53:22 +02:00
Joris Vink c4c60e1960 Oops, make sure the new simple api can handle > 1 request without borking. 2014-09-19 14:49:12 +02:00
Joris Vink f6f37437da In pgsql_simple_state_result() be sure to progress the sql state.
Drop back into waiting after our result so we can properly read out
the completed state.
2014-09-19 12:51:37 +02:00
Joris Vink 8e9c3da764 Add a new "simple query" layer to our pgsql api.
This simple query allows you to ditch rolling your own
state machine for handling async pgsql states and instead
asks you to provide 3 functions:
	- init
	- results
	- done

You can see the different in complexity in the pgsql example,
which now contains a pgsql_simple.c holding the same asynchronous
query as in pgsql.c but using the simple pgsql api.

You can of course still roll your own in case you want more control.
2014-09-19 12:32:49 +02:00
Joris Vink 73055662de Remove start from pgsql_job 2014-09-18 10:49:15 +02:00
Joris Vink 7e74cd6e62 Introduce a wait queue for our pgsql code.
Instead of letting http_requests spin, if we cannot allocate
a connection for the request we will queue them up put them to sleep.

When a connection becomes available, we'll wake up a request that
was waiting for a connection and let it continue.

This completely avoids consuming massive amounts of cpu time
when dealing with thousands of requests waiting for a pgsql
worker to become ready.
2014-08-21 16:36:12 +02:00
Joris Vink 8565b47800 Attach tasks/pgsqls to http_requests once more.
This way if an http request is removed while tasks or
pgsqls are still active they are free'd out and cancelled
properly.
2014-08-14 22:05:34 +02:00
Joris Vink f021c8db44 pgsql improvements
* set pgsql->result to NULL when we freed it
* drain the connection pipe just in case in pgsql_conn_release()
2014-08-14 16:43:40 +02:00
Joris Vink 9ea1e3cb57 Properly release pgsql connection if needed 2014-08-14 14:46:21 +02:00
Joris Vink f93747828c Major pgsql rework.
Gone is the ugly KORE_PGSQL macro that hid an overly complex
state machine for the pgsql api.
Gone is the pgsql array that was attached to http_requests.
Gone are the callback hacks inside the pgsql api.

Instead, I strongly encourage people to use the new state machine
api Kore offers to properly deal with asynchronous queries.

The pgsql example in examples/pgsql has been updated to reflect
these changes.
2014-08-14 14:34:23 +02:00
Joris Vink a5806d91f8 Pull in pg_config.h correctly, fixes compilation for pgsql under OpenBSD 2014-07-18 15:59:07 +02:00
Joris Vink 19d146a09e Introduce http_request_sleep() and http_request_wakeup().
These 2 functions can be used to move an HTTP request
from/to the active http_requests list. Effectively
putting them to "sleep" or "waking them up".

Sprinkle this through the pgsql and task code.

If used correctly greatly reduces overhead for
managing sleeping tasks.
2014-07-04 16:51:19 +02:00
Joris Vink 1ad9f039ab Add pgsql_conn_max configuration parameter.
Allows you to tune how many pgsql connections kore
will make at one time.
2014-07-04 09:14:05 +02:00
Joris Vink 8b20dec081 Add missing pg_config.h header 2014-07-04 09:03:19 +02:00
Joris Vink 8e0ab8cc61 Check for pg version >= 90200 before using PGRES_SINGLE_TUPLE 2014-07-03 22:58:04 +02:00