Page MenuHomePhorge

No OneTemporary

Size
11 KB
Referenced Files
None
Subscribers
None
diff --git a/.formatter.exs b/.formatter.exs
new file mode 100644
index 0000000..323fd85
--- /dev/null
+++ b/.formatter.exs
@@ -0,0 +1,4 @@
+# Used by "mix format"
+[
+ inputs: ["{mix,.formatter}.exs", "{config,lib,test,benchmarks}/**/*.{ex,exs}"]
+]
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d4ecc92
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,24 @@
+# The directory Mix will write compiled artifacts to.
+/_build/
+
+# If you run "mix test --cover", coverage assets end up here.
+/cover/
+
+# The directory Mix downloads your dependencies sources to.
+/deps/
+
+# Where third-party dependencies like ExDoc output generated docs.
+/doc/
+
+# Ignore .fetch files in case you like to edit your project deps locally.
+/.fetch
+
+# If the VM crashes, it generates a dump, let's ignore it too.
+erl_crash.dump
+
+# Also ignore archive artifacts (built via "mix archive.build").
+*.ez
+
+# Ignore package tarball (built via "mix hex.build").
+ano_pool-*.tar
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..41f6925
--- /dev/null
+++ b/README.md
@@ -0,0 +1,21 @@
+# AnoPool
+
+**TODO: Add description**
+
+## Installation
+
+If [available in Hex](https://hex.pm/docs/publish), the package can be installed
+by adding `ano_pool` to your list of dependencies in `mix.exs`:
+
+```elixir
+def deps do
+ [
+ {:ano_pool, "~> 0.1.0"}
+ ]
+end
+```
+
+Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
+and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
+be found at [https://hexdocs.pm/ano_pool](https://hexdocs.pm/ano_pool).
+
diff --git a/benchmarks/main.exs b/benchmarks/main.exs
new file mode 100644
index 0000000..813df84
--- /dev/null
+++ b/benchmarks/main.exs
@@ -0,0 +1,153 @@
+defmodule AnoPool.Benchmark.CowboyHandler do
+ def init(req, state) do
+ bytes = :cowboy_req.binding(:bytes, req)
+ bits = bytes * 8
+ chunk_size = :cowboy_req.binding(:chunk_size, req, nil)
+
+ unless chunk_size do
+ req =
+ :cowboy_req.reply(
+ 200,
+ %{"content-type" => "application/octet-stream"},
+ <<0::size(bits)>>,
+ req
+ )
+
+ {:ok, req, state}
+ else
+ req = :cowboy_req.stream_reply(200, %{"content-type" => "application/octet-stream"}, req)
+ req = stream_body(req, bytes, chunk_size)
+ {:ok, req, state}
+ end
+ end
+
+ defp stream_body(req, bytes, chunk_size) do
+ if bytes - chunk_size < 0 do
+ bits = bytes * 8
+ :cowboy_req.stream_body(<<0::size(bits)>>, :fin, req)
+ else
+ bits = chunk_size * 8
+ :cowboy_req.stream_body(<<0::size(bits)>>, :nofin, req)
+ stream_body(req, bytes - chunk_size, chunk_size)
+ end
+ end
+end
+
+dispatch =
+ :cowboy_router.compile([
+ {:_,
+ [
+ {"/:bytes/[:chunk_size]", [{:bytes, :int}, {:chunk_size, :int}],
+ AnoPool.Benchmark.CowboyHandler, %{}}
+ ]}
+ ])
+
+{:ok, _} =
+ :cowboy.start_clear(:benchmark_http_clear_listener, [], %{
+ env: %{dispatch: dispatch}
+ })
+
+http_clear_port = :ranch.get_port(:benchmark_http_clear_listener)
+
+{:ok, _} =
+ :cowboy.start_clear(:benchmark_http2_clear_listener, [], %{
+ env: %{dispatch: dispatch},
+ protocols: [:http2]
+ })
+
+http2_clear_port = :ranch.get_port(:benchmark_http2_clear_listener)
+
+defmodule AnoPool.Benchmark.Helpers do
+ def handle_mint_response(conn, ref, state \\ %{}) do
+ receive do
+ message ->
+ case Mint.HTTP.stream(conn, message) do
+ :unknown ->
+ handle_mint_response(conn, state)
+
+ {:ok, conn, responses} ->
+ state =
+ Enum.reduce(responses, state, fn
+ {:status, ^ref, status_code}, state ->
+ Map.put(state, :status_code, status_code)
+
+ {:headers, ^ref, headers}, state ->
+ Map.put(state, :headers, headers)
+
+ {:data, ^ref, chunk}, state ->
+ if data = state[:data] do
+ data = data <> chunk
+ %{state | data: data}
+ else
+ Map.put(state, :data, chunk)
+ end
+
+ {:done, ^ref}, state ->
+ Map.put(state, :fin, true)
+ end)
+
+ unless state[:fin] do
+ handle_mint_response(conn, ref, state)
+ else
+ {state.status_code, state.headers, state.data, fn -> Mint.HTTP.close(conn) end}
+ end
+ end
+ end
+ end
+end
+
+inputs =
+ Enum.flat_map(
+ %{
+ "1MB transfer without chunks" => "/1048576",
+ "8MB transfer, chunked by 1MB" => "/8388608/1048576",
+ "20MB transfer, chunked by 1MB" => "/20971520/1048576"
+ },
+ fn {key, path} ->
+ [
+ {"HTTP1 over TCP: " <> key, {path, :http, http_clear_port}},
+ {"HTTP2 over TCP: " <> key, {path, :http2, http2_clear_port}}
+ ]
+ end
+ )
+ |> Enum.into(%{})
+
+Benchee.run(
+ %{
+ "raw gun stream 1mb" => fn {path, proto, port} ->
+ {:ok, conn} = :gun.open('127.0.0.1', port, %{protocols: [proto]})
+ :gun.await_up(conn)
+ stream = :gun.get(conn, path)
+ {:response, :nofin, status, headers} = :gun.await(conn, stream)
+ {:ok, body} = :gun.await_body(conn, stream)
+ teardown = fn -> :gun.shutdown(conn) end
+ {status, headers, body, teardown}
+ end,
+ "raw mint stream 1mb" => fn {path, proto, port} ->
+ proto =
+ case proto do
+ :http -> :http1
+ proto -> proto
+ end
+
+ {:ok, conn} = Mint.HTTP.connect(:http, "127.0.0.1", port, protocols: [proto])
+ {:ok, conn, request_ref} = Mint.HTTP.request(conn, "GET", path, [], nil)
+ AnoPool.Benchmark.Helpers.handle_mint_response(conn, request_ref)
+ end
+ },
+ inputs: inputs,
+ after_each: fn {status, headers, body, teardown} ->
+ teardown.()
+ 200 = status
+
+ {"content-type", "application/octet-stream"} =
+ Enum.find(headers, fn
+ {"content-type", _} -> true
+ _ -> false
+ end)
+
+ size = bit_size(body)
+ <<0::size(size)>> = body
+ :timer.sleep(10)
+ end
+)
diff --git a/lib/ano_pool.ex b/lib/ano_pool.ex
new file mode 100644
index 0000000..f4b5d6f
--- /dev/null
+++ b/lib/ano_pool.ex
@@ -0,0 +1,18 @@
+defmodule AnoPool do
+ @moduledoc """
+ Documentation for `AnoPool`.
+ """
+
+ @doc """
+ Hello world.
+
+ ## Examples
+
+ iex> AnoPool.hello()
+ :world
+
+ """
+ def hello do
+ :world
+ end
+end
diff --git a/mix.exs b/mix.exs
new file mode 100644
index 0000000..2f06f92
--- /dev/null
+++ b/mix.exs
@@ -0,0 +1,36 @@
+defmodule AnoPool.MixProject do
+ use Mix.Project
+
+ def project do
+ [
+ app: :ano_pool,
+ version: "0.1.0",
+ elixir: "~> 1.10",
+ start_permanent: Mix.env() == :prod,
+ deps: deps(),
+ preferred_cli_env: [bench: :bench],
+ aliases: [bench: "run benchmarks/main.exs"]
+ ]
+ end
+
+ # Run "mix help compile.app" to learn about applications.
+ def application do
+ [
+ extra_applications: [:logger]
+ ]
+ end
+
+ # Run "mix help deps" to learn about dependencies.
+ defp deps do
+ [
+ # {:dep_from_hexpm, "~> 0.3.0"},
+ # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
+ {:cowboy, "~> 2.8", only: [:bench]},
+ {:benchee, "~> 1.0", only: [:bench]},
+ {:finch, "~> 0.3", only: [:bench]},
+ {:gun,
+ git: "https://github.com/ninenines/gun", ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327"},
+ {:cowlib, "~> 2.9.1", override: true}
+ ]
+ end
+end
diff --git a/mix.lock b/mix.lock
new file mode 100644
index 0000000..ed4a536
--- /dev/null
+++ b/mix.lock
@@ -0,0 +1,14 @@
+%{
+ "benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"},
+ "castore": {:hex, :castore, "0.1.7", "1ca19eee705cde48c9e809e37fdd0730510752cc397745e550f6065a56a701e9", [:mix], [], "hexpm", "a2ae2c13d40e9c308387f1aceb14786dca019ebc2a11484fb2a9f797ea0aa0d8"},
+ "cowboy": {:hex, :cowboy, "2.8.0", "f3dc62e35797ecd9ac1b50db74611193c29815401e53bac9a5c0577bd7bc667d", [:rebar3], [{:cowlib, "~> 2.9.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "~> 1.7.1", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "4643e4fba74ac96d4d152c75803de6fad0b3fa5df354c71afdd6cbeeb15fac8a"},
+ "cowlib": {:hex, :cowlib, "2.9.1", "61a6c7c50cf07fdd24b2f45b89500bb93b6686579b069a89f88cb211e1125c78", [:rebar3], [], "hexpm", "e4175dc240a70d996156160891e1c62238ede1729e45740bdd38064dad476170"},
+ "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
+ "finch": {:hex, :finch, "0.3.1", "55d3d38eb61cd8356b6e1c696d3c526ed5b2c4e1f8643096e66a100f88001c79", [:mix], [{:castore, "~> 0.1.5", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.2.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.1.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5c47c6d05d95b1587b57784782a327d1b26952baf295f7044cbb91e829836ee9"},
+ "gun": {:git, "https://github.com/ninenines/gun", "921c47146b2d9567eac7e9a4d2ccc60fffd4f327", [ref: "921c47146b2d9567eac7e9a4d2ccc60fffd4f327"]},
+ "mint": {:hex, :mint, "1.1.0", "1fd0189edd9e3ffdbd7fcd8bc3835902b987a63ec6c4fd1aa8c2a56e2165f252", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "5bfd316c3789340b682d5679a8116bcf2112e332447bdc20c1d62909ee45f48d"},
+ "nimble_options": {:hex, :nimble_options, "0.2.1", "7eac99688c2544d4cc3ace36ee8f2bf4d738c14d031bd1e1193aab096309d488", [:mix], [], "hexpm", "ca48293609306791ce2634818d849b7defe09330adb7e4e1118a0bc59bed1cf4"},
+ "nimble_pool": {:hex, :nimble_pool, "0.1.0", "ffa9d5be27eee2b00b0c634eb649aa27f97b39186fec3c493716c2a33e784ec6", [:mix], [], "hexpm", "343a1eaa620ddcf3430a83f39f2af499fe2370390d4f785cd475b4df5acaf3f9"},
+ "ranch": {:hex, :ranch, "1.7.1", "6b1fab51b49196860b733a49c07604465a47bdb78aa10c1c16a3d199f7f8c881", [:rebar3], [], "hexpm", "451d8527787df716d99dc36162fca05934915db0b6141bbdac2ea8d3c7afc7d7"},
+ "telemetry": {:hex, :telemetry, "0.4.2", "2808c992455e08d6177322f14d3bdb6b625fbcfd233a73505870d8738a2f4599", [:rebar3], [], "hexpm", "2d1419bd9dda6a206d7b5852179511722e2b18812310d304620c7bd92a13fcef"},
+}
diff --git a/test/ano_pool_test.exs b/test/ano_pool_test.exs
new file mode 100644
index 0000000..d0a9f4e
--- /dev/null
+++ b/test/ano_pool_test.exs
@@ -0,0 +1,8 @@
+defmodule AnoPoolTest do
+ use ExUnit.Case
+ doctest AnoPool
+
+ test "greets the world" do
+ assert AnoPool.hello() == :world
+ end
+end
diff --git a/test/test_helper.exs b/test/test_helper.exs
new file mode 100644
index 0000000..869559e
--- /dev/null
+++ b/test/test_helper.exs
@@ -0,0 +1 @@
+ExUnit.start()

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 6:43 PM (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
40009
Default Alt Text
(11 KB)

Event Timeline