Commit Graph

13 Commits

Author SHA1 Message Date
Daniel Sockwell daf7d1ae7f
Add tests for polling for multiple messages (#149)
* Add tests for polling for multiple messages

This commit adds a mock Redis interface and adds tests that poll the
mock interface for multiple messages at a time.  These tests test that
Flodgatt is robust against receiving incomplete messages, including if
the message break results in receiving invalid UTF8.

* Remove temporary files
2020-05-07 10:56:11 -04:00
Daniel Sockwell 4a13412f98
Improve handling of large Redis input (#143)
* Implement faster buffered input

This commit implements a modified ring buffer for input from Redis.
Specifically, Flodgatt now limits the amount of data it fetches from
Redis in one syscall to 8 KiB (two pages on most systems). Flodgatt
will process all complete messages it receives from Redis and then
re-use the same buffer for the next time it retrieves data.  If
Flodgatt received a partial message, it will copy the partial message
to the beginning of the buffer before its next read.

This change has little effect on Flodgatt under light load (because it
was rare for Redis to have more than 8 KiB of messages available at
any one time).  However, my hope is that this will significantly
reduce memory use on the largest instances.

* Improve handling of backpresure

This commit alters how Flodgatt behaves if it receives enough messages
for a single client to fill that clients channel. (Because the clients
regularly send their messages, should only occur if a single client
receives a large number of messages nearly simultaneously; this is
rare, but could occur, especially on large instances).

Previously, Flodgatt would drop messages in the rare case when the
client's channel was full.  Now, Flodgatt will pause the current Redis
poll and yield control back to the client streams, allowing the
clients to empty their channels; Flodgatt will then resume polling
Redis/sending the messages it previously received.  With the approach,
Flodgatt will never drop messages.

However, the risk to this approach is that, by never dropping
messages, Flodgatt does not have any way to reduce the amount of work
it needs to do when under heavy load – it delays the work slightly,
but doesn't reduce it.  What this means is that it would be
*theoretically* possible for Flodgatt to fall increasingly behind, if
it is continuously receiving more messages than it can process.  Due
to how quickly Flodgatt can process messages, though, I suspect this
would only come up if an admin were running Flodgatt in a
*significantly* resource constrained environment, but I wanted to
mention it for the sake of completeness.

This commit also adds a new /status/backpressure endpoint that
displays the current length of the Redis input buffer (which should
typically be low or 0).  Like the other /status endpoints, this
endpoint is only enabled when Flodgatt is compiled with the
`stub_status` feature.
2020-04-27 16:03:05 -04:00
Daniel Sockwell 016f49a2d8
Improve module privacy (#136)
* Adjust module privacy

* Use trait object

* Finish module privacy refactor
2020-04-22 14:38:22 -04:00
Daniel Sockwell 10fa24c5d3
Benchmark & performance tune (#132)
* Add temporary perf metrics

* Add load testing and tune performance
2020-04-17 17:07:10 -04:00
Daniel Sockwell 19792d9484
Handle non conforment events (#117)
* Initial implementation of DynamicEvent

* Restore early Event parsing
2020-04-03 12:41:53 -04:00
Daniel Sockwell 5965a514fd
Reorganize code, pt2 (#112)
* Cleanup RedisMsg parsing [WIP]

* Add tests to Redis parsing

* WIP RedisMsg refactor

Committing WIP before trying a different approach

* WIP

* Refactor RedisConn and Receiver

* Finish second reorganization
2020-03-30 18:54:00 -04:00
Daniel Sockwell 0acbde3eee
Reorganize code, pt1 (#110)
* Prevent Reciever from querying postgres

Before this commit, the Receiver would query Postgres for the name
associated with a hashtag when it encountered one not in its cache.
This ensured that the Receiver never encountered a (valid) hashtag id
that it couldn't handle, but caused a extra DB query and made
independent sections of the code more entangled than they need to be.

Now, we pass the relevant tag name to the Receiver when it first
starts managing a new subscription and it adds the tag name to its
cache then.

* Improve module boundary/privacy

* Reorganize Receiver to cut RedisStream

* Fix tests for code reorganization

Note that this change includes testing some private functionality by
exposing it publicly in tests via conditional compilation.  This
doesn't expose that functionality for the benchmarks, so the benchmark
tests do not currently pass without adding a few `pub use`
statements.  This might be worth changing later, but benchmark tests
aren't part of our CI and it's not hard to change when we want to test
performance.

This change also cuts the benchmark tests that were benchmarking old
ways Flodgatt functioned.  Those were useful for comparison purposes,
but have served their purpose – we've firmly moved away from the
older/slower approach.

* Fix Receiver for tests
2020-03-27 12:00:48 -04:00
Daniel Sockwell 2dd9ccbf91
Performance tuning (#108)
* Initial implementation WIP

* Add Event type for faster parsing

* Add tests and benchmarks

* Add additional parsing tests
2020-03-25 17:50:32 -04:00
Daniel Sockwell 5482be9414
Fix dev dependencies for benchmarks (#82) 2020-01-09 18:17:01 -05:00
Daniel Sockwell 5b663d110e
Unicode fix (#54)
* Increase detail of error logging; bump version

* Fix panic caused by spliting a message inside a Unicode char
2019-10-01 09:28:43 -04:00
Daniel Sockwell fc7feb6694
Speed improvment to redis_parse (#52) 2019-09-28 12:27:45 -04:00
Daniel Sockwell 2ac08c5316
Parse redis messages (#51)
* Initial version of Redis parsing fix

* Refactor parsing for more maintainability

* Add benchmarks for new parsing strategy

* Add tests for parsing
2019-09-27 23:29:11 -04:00
Daniel Sockwell ceb38c2689
Add initial benchmarks (#50) 2019-09-11 17:28:27 -04:00