GithubHelp home page GithubHelp logo

Comments (12)

mtrudel avatar mtrudel commented on June 10, 2024

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.

hauleth avatar hauleth commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

Yep, I see the issue now!

Should be an easy fix! Stay tuned.

from thousand_island.

hauleth avatar hauleth commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

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.

hauleth avatar hauleth commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

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.

hauleth avatar hauleth commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

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.

mtrudel avatar mtrudel commented on June 10, 2024

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 the shutdown_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.

hauleth avatar hauleth commented on June 10, 2024

I will check that out today.

from thousand_island.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.