Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F114038
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Award Token
Flag For Later
Size
11 KB
Referenced Files
None
Subscribers
None
View Options
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
Details
Attached
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)
Attached To
Mode
R24 pool-benchmark
Attached
Detach File
Event Timeline
Log In to Comment