Comments (12)
As I'm sure you have figured out Thousand Island just passes parameters down into :gen_tcp
/ :ssl
without altering them at all; literally anything that's possible to do directly should transparently be possible within Thousand Island as well (at least, that's the intent).
Let me dig into this for a moment; it's possible that I've somehow gotten in the way of that being the case.
from thousand_island.
Yes, it technically is possible, but the problem is that Keyword.merge/2
will fail if one of the lists is non-keyword list [:inet6, fd: 1]
is not keyword list.
from thousand_island.
Yep, I see the issue now!
Should be an easy fix! Stay tuned.
from thousand_island.
My quick and dirty solution was to do something like:
@impl Transport
def listen(port, user_options) do
default_options = [
backlog: 1024,
nodelay: true,
linger: {true, 30},
send_timeout: 30_000,
send_timeout_close: true,
reuseaddr: true
]
{inet, user_options} = Keyword.pop(user_options, :net, :inet)
resolved_options =
default_options |> Keyword.merge(user_options) |> Keyword.merge(@hardcoded_options)
:gen_tcp.listen(port, [inet | resolved_options])
end
But it is still limited to supporting only inet6
/inet
option, and it will not support other options that do not conform to "keyword list definition" (for example raw
option).
from thousand_island.
Fix is up at #26 - is it possible for you to test this branch & verify it fixes your issue? I've tested locally with a bare :inet6
parameter and it works, but I didn't go the whole way of tying with an open FD.
(I'd love a PR describing how to do that, btw!)
from thousand_island.
I have updated Plug example in systemd
library with Bandit support - hauleth/erlang-systemd@81e98d3. It still has some problem with draining from what I see. I cannot find a way to make it work better though and the amount of dropped requests is small enough that it shouldn't be a problem.
from thousand_island.
That's awesome to hear! I'll merge the changes in #26 and tag a TI / Bandit release later today so you can ensure your dependency has that fix included.
Thousand Island's drain support is based entirely on OTP shutdown semantics within the Thousand Island process tree, and should generally be opaque (the parent TI supervisor process will wait up to 5s* for connections to close, at which point they'll be brutally killed). I'd be curious to see a repro case for drain failures; it's entirely possible there are bugs.
* This isn't yet configurable, but I'll be adding in a configuration point to Thousand Island for it as part of the Bandit 0.7 train later this year.
from thousand_island.
The reproducing code is in the repo I have linked. Details can be found there hauleth/erlang-systemd#24 (comment). In short if you run the service via systemd make
in the example/plug
directory on systemd-enabled Linux (beware, that it installs example app globally in /opt
and uses sudo
, so it is best done in throwaway VM rather on host). And then when you run any HTTP benmcharking tool and issue systemctl stop plug.service
then there should be no connection errors. Currently there are few of them. Not enough IMHO to worry, but ideally I would like to see 0 of them. The problem is that I do not know whether it is problem on systemd or Elixir/Erlang side.
from thousand_island.
Any connections which are still open after 5 seconds will be brutally killed, which is likely what's happening here. The issue comes from the fact that 'connection' in this sense is at the network layer, not the application layer.
Specifically, HTTP connections that make use of keep-alive will happily continue accepting subsequent requests all the way until they're brutally killed (likely mid-way through a request).
I'll make a note to look at improving the drain process' integration with the upper level protocol handler (Bandit, in this case).
from thousand_island.
The fix in #26 has been published in Thousand Island 0.5.13, which is now a dependency of of Bandit 0.6.1. You may want to update the mix.lock dep in hauleth/erlang-systemd@81e98d3 to reflect that, as it's a bit out of date.
Thanks for the great suggestion!
from thousand_island.
Specifically, HTTP connections that make use of keep-alive will happily continue accepting subsequent requests all the way until they're brutally killed (likely mid-way through a request).
I'll make a note to look at improving the drain process' integration with the upper level protocol handler (Bandit, in this case).
This is not, in fact, the case. I've verified that (at least for HTTP/1.1):
- Connections which are in a keep-alive & waiting for a subsequent request to come in will be killed cleanly & immediately at server shutdown. They DO NOT stick around waiting.
- Connections which are mid-way through generating a response will complete the response (ie: they will complete the
Bandit.HTTP1.Handler.handle_data/3
call that they're in) before being cleanly killed. That is, assuming that the response generation completes before theshutdown_timeout
expires & they're brutally killed.
I'll also note that Thousand Island 0.6.3 (released a few days ago) supports configurability of the shutdown_timeout
, and also ups its value to 15 seconds by default (up from 5 seconds previously).
from thousand_island.
I will check that out today.
from thousand_island.
Related Issues (20)
- Slow accepting HOT 2
- handling non-TI messages within same GenServer fails after PR#96 HOT 1
- Feature request: Let the process outlive beyond the connection HOT 9
- Using the ThousandIsland.Handler "escape hatch" HOT 6
- GenServer #PID<0.656.0> terminating HOT 2
- Support for UDP transport HOT 12
- Question: would `controlling_process/2` be a potential bottleneck? HOT 12
- Process isolation between requests HOT 6
- Acceptor pool race condition HOT 6
- Cannot start multiple ThousandIsland children under a Supervisor HOT 5
- GenServer `:tls_alert` error on handshake failure HOT 6
- Unexpected error in accept: :emfile HOT 26
- Thoughts on adopting PartitionSupervisor HOT 4
- docs are unclear about GenServer handle_* calls cancelling read timeouts HOT 3
- problems with tcpkali HOT 4
- configurable acceptor pools HOT 2
- FunctionClauseError randomly happens HOT 2
- Upgrading the transport mid-connection HOT 6
- Inconsistent callback invoked when data received HOT 6
- A way to align custom and library `GenServer` responses HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from thousand_island.