nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: phoenixframework/phoenix_html
Pull request #316 (2020-09-18 15:55:17)

Use to_iso8601 as the standard implementation for safe dates and times
Most browsers are fine with with the non-iso-standard to_string we provide in Elixir that does not include the T but some browsers, Safari in particular, will choke and blow up. Using the ISO standard as a default and asking the user to format or choose their own representation is a more clear choice. 

This change does regress and will not use a users configured timezone abbr by default but they can simply call the function to fix that. 

(Please ignore the branch name)


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3cb0254..bac02c3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,9 @@
 # Changelog
 
-## v2.15-dev
+# v3.0.0-dev
+
+* Backwards incompatible changes 
+  * By default dates and times will format to the `to_iso8601` functions provided by their implementation
 
 ## v2.14.2 (2020-04-30)
 
diff --git a/lib/phoenix_html/safe.ex b/lib/phoenix_html/safe.ex
index a231885..c1e665b 100644
--- a/lib/phoenix_html/safe.ex
+++ b/lib/phoenix_html/safe.ex
@@ -25,22 +25,22 @@ defimpl Phoenix.HTML.Safe, for: BitString do
 end
 
 defimpl Phoenix.HTML.Safe, for: Time do
-  defdelegate to_iodata(data), to: Time, as: :to_string
+  defdelegate to_iodata(data), to: Time, as: :to_iso8601
 end
 
 defimpl Phoenix.HTML.Safe, for: Date do
-  defdelegate to_iodata(data), to: Date, as: :to_string
+  defdelegate to_iodata(data), to: Date, as: :to_iso8601
 end
 
 defimpl Phoenix.HTML.Safe, for: NaiveDateTime do
-  defdelegate to_iodata(data), to: NaiveDateTime, as: :to_string
+  defdelegate to_iodata(data), to: NaiveDateTime, as: :to_iso8601
 end
 
 defimpl Phoenix.HTML.Safe, for: DateTime do
   def to_iodata(data) do
     # Call escape in case someone can inject reserved
     # characters in the timezone or its abbreviation
-    Phoenix.HTML.Engine.html_escape(DateTime.to_string(data))
+    Phoenix.HTML.Engine.html_escape(DateTime.to_iso8601(data))
   end
 end
 


Test patch:
diff --git a/test/phoenix_html/safe_test.exs b/test/phoenix_html/safe_test.exs
index 865802a..e9c5b60 100644
--- a/test/phoenix_html/safe_test.exs
+++ b/test/phoenix_html/safe_test.exs
@@ -41,7 +41,7 @@ defmodule Phoenix.HTML.SafeTest do
 
   test "impl for NaiveDateTime" do
     {:ok, datetime} = NaiveDateTime.new(2000, 1, 1, 12, 13, 14)
-    assert Safe.to_iodata(datetime) == "2000-01-01 12:13:14"
+    assert Safe.to_iodata(datetime) == "2000-01-01T12:13:14"
   end
 
   test "impl for DateTime" do
@@ -59,10 +59,6 @@ defmodule Phoenix.HTML.SafeTest do
       utc_offset: 3600
     }
 
-    assert Safe.to_iodata(datetime) ==
-             [
-               [[[[], "2000-01-01 12:13:14+00:30 " | "&lt;"], "H" | "&gt;"], " " | "&lt;"],
-               "Hello" | "&gt;"
-             ]
+    assert Safe.to_iodata(datetime) == "2000-01-01T12:13:14+00:30"
   end
 end
Repository: phoenixframework/phoenix_html
Pull request #347 (2021-08-14 17:11:37)

Add csrf_input_tag/2 helper


Patch:
diff --git a/lib/phoenix_html/tag.ex b/lib/phoenix_html/tag.ex
index 22a84fb..6327698 100644
--- a/lib/phoenix_html/tag.ex
+++ b/lib/phoenix_html/tag.ex
@@ -291,7 +291,7 @@ defmodule Phoenix.HTML.Tag do
   end
 
   @doc """
-  Returns the csrf_token value to be used by forms, meta tags, etc.
+  Returns the `csrf_token` value to be used by forms, meta tags, etc.
 
   By default, CSRF tokens are generated through `Plug.CSRFProtection`
   which is capable of generating a separate token per host. Therefore
@@ -313,6 +313,30 @@ defmodule Phoenix.HTML.Tag do
     tag(:meta, [name: "csrf-token", content: csrf_token_value()] ++ opts)
   end
 
+  @doc """
+  Generates a hidden input tag with a CSRF token.
+
+  This could be used when writing a form without the use of tag
+  helpers like `form_tag/3` or `form_for/4`, while maintaining
+  CSRF protection.
+
+  The `to` argument should be the same as the form action.
+
+  ## Example
+
+      <form action="/login" method="POST">
+        <%= csrf_input_tag("/login") %>
+
+        etc.
+      </form>
+
+  Additional options to the tag can be given.
+  """
+  def csrf_input_tag(to, opts \\ []) do
+    csrf_token = csrf_token_value(to)
+    tag(:input, [type: "hidden", name: @csrf_param, value: csrf_token] ++ opts)
+  end
+
   @doc """
   Generates an img tag with a src.
 


Test patch:
diff --git a/test/phoenix_html/tag_test.exs b/test/phoenix_html/tag_test.exs
index 2f14a8e..979479d 100644
--- a/test/phoenix_html/tag_test.exs
+++ b/test/phoenix_html/tag_test.exs
@@ -227,6 +227,17 @@ defmodule Phoenix.HTML.TagTest do
              ~s(<meta content="#{csrf_token}" foo="bar" name="csrf-token">)
   end
 
+  test "csrf_input_tag" do
+    url = "/example"
+    csrf_token = Plug.CSRFProtection.get_csrf_token_for(url)
+
+    assert safe_to_string(csrf_input_tag(url)) ==
+             ~s(<input name="_csrf_token" type="hidden" value="#{csrf_token}">)
+
+    assert safe_to_string(csrf_input_tag(url, foo: "bar")) ==
+             ~s(<input foo="bar" name="_csrf_token" type="hidden" value="#{csrf_token}">)
+  end
+
   describe "csrf_token_value" do
     def custom_csrf(to, extra), do: "#{extra}:#{to}"
Repository: phoenixframework/phoenix_html
Pull request #381 (2022-05-11 02:05:26)

Fix `checkbox` generating wrong `id` parameter for multi checkbox case
Previously, the same ID would be generated for all checkboxes.

josevalim: Given this is the third request in 1 month for this feature, we should probably do it, yeah. :)

Patch:
diff --git a/lib/phoenix_html/form.ex b/lib/phoenix_html/form.ex
index e3b2759..068a76d 100644
--- a/lib/phoenix_html/form.ex
+++ b/lib/phoenix_html/form.ex
@@ -1041,7 +1041,6 @@ defmodule Phoenix.HTML.Form do
     opts =
       opts
       |> Keyword.put_new(:type, "checkbox")
-      |> Keyword.put_new(:id, input_id(form, field))
       |> Keyword.put_new(:name, input_name(form, field))
 
     {value, opts} = Keyword.pop(opts, :value, input_value(form, field))
@@ -1056,10 +1055,16 @@ defmodule Phoenix.HTML.Form do
     unchecked_value = html_escape(unchecked_value)
 
     opts =
-      Keyword.put_new_lazy(opts, :checked, fn ->
+      opts
+      |> Keyword.put_new_lazy(:checked, fn ->
         value = html_escape(value)
         value == checked_value
       end)
+      |> Keyword.put_new_lazy(:id, fn ->
+        if String.ends_with?(opts[:name], "[]"),
+          do: input_id(form, field, checked_value),
+          else: input_id(form, field)
+      end)
 
     if hidden_input do
       hidden_opts = [type: "hidden", value: unchecked_value]


Test patch:
diff --git a/test/phoenix_html/form_test.exs b/test/phoenix_html/form_test.exs
index 12b09c5..0fe2af7 100644
--- a/test/phoenix_html/form_test.exs
+++ b/test/phoenix_html/form_test.exs
@@ -818,7 +818,7 @@ defmodule Phoenix.HTML.FormTest do
                hidden_input: false
              )
            ) ==
-             ~s(<input id="search_key" name="search[key][]" type="checkbox" value="c">)
+             ~s(<input id="search_key_c" name="search[key][]" type="checkbox" value="c">)
   end
 
   test "checkbox/3 with form" do
Repository: phoenixframework/phoenix_html
Pull request #404 (2023-02-03 23:25:44)

Add field to FormField struct

josevalim: I think we should merge this but for completeness we will eventually have to support string keys and then field will have to be a string too, but that’s ok.

Patch:
diff --git a/lib/phoenix_html/form.ex b/lib/phoenix_html/form.ex
index 7bd2321..0437847 100644
--- a/lib/phoenix_html/form.ex
+++ b/lib/phoenix_html/form.ex
@@ -281,6 +281,7 @@ defmodule Phoenix.HTML.Form do
     {:ok,
      %Phoenix.HTML.FormField{
        errors: Keyword.get_values(errors, field),
+       field: field,
        form: form,
        id: input_id(form, field_as_string),
        name: input_name(form, field_as_string),
diff --git a/lib/phoenix_html/form_field.ex b/lib/phoenix_html/form_field.ex
index 44ac813..a770d97 100644
--- a/lib/phoenix_html/form_field.ex
+++ b/lib/phoenix_html/form_field.ex
@@ -5,12 +5,13 @@ defmodule Phoenix.HTML.FormField do
   It has the following fields:
 
     * `:errors` - a list of errors belonging to the field
+    * `:field` - the field name as an atom
     * `:form` - the parent `form` struct
     * `:id` - the `id` to be used as form input as a string
     * `:name` - the `name` to be used as form input as a string
     * `:value` - the value for the input
 
   """
-  @enforce_keys [:id, :name, :errors, :form, :value]
-  defstruct [:id, :name, :errors, :form, :value]
+  @enforce_keys [:id, :name, :errors, :field, :form, :value]
+  defstruct [:id, :name, :errors, :field, :form, :value]
 end


Test patch:
diff --git a/test/phoenix_html/form_test.exs b/test/phoenix_html/form_test.exs
index 77b1f03..f41e7a6 100644
--- a/test/phoenix_html/form_test.exs
+++ b/test/phoenix_html/form_test.exs
@@ -229,6 +229,7 @@ defmodule Phoenix.HTML.FormTest do
       form = form(%{"key" => "value"})
 
       assert form[:key] == %Phoenix.HTML.FormField{
+               field: :key,
                id: "key",
                form: form,
                value: "value",
@@ -241,6 +242,7 @@ defmodule Phoenix.HTML.FormTest do
       form = form(%{"key" => "value"}, as: :search)
 
       assert form[:key] == %Phoenix.HTML.FormField{
+               field: :key,
                id: "search_key",
                form: form,
                value: "value",
Repository: general-CbIC/poolex
Pull request #45 (2023-06-03 06:16:53)

Handle shutdown process
Add `terminate/2` callback to Poolex's GenServer to handle the shutdown process.

This relates to issue #44.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b132e68..fd4139d 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
+### Fixed
+
+- Fix the shutdown process: stop workers before the pool ([issue](https://github.com/general-CbIC/poolex/issues/44)).
+
 ## [0.7.0] - 2023-04-13
 
 ### Added
diff --git a/lib/poolex.ex b/lib/poolex.ex
index bb8fd2f..c130c6b 100644
--- a/lib/poolex.ex
+++ b/lib/poolex.ex
@@ -472,4 +472,12 @@ defmodule Poolex do
         {:noreply, %{state | waiting_callers_state: new_waiting_callers_state}}
     end
   end
+
+  @impl GenServer
+  def terminate(reason, %State{} = state) do
+    DynamicSupervisor.stop(state.supervisor, reason)
+    Monitoring.stop(state.monitor_id)
+
+    :ok
+  end
 end
diff --git a/lib/poolex/monitoring.ex b/lib/poolex/monitoring.ex
index 7acee15..3f4a682 100644
--- a/lib/poolex/monitoring.ex
+++ b/lib/poolex/monitoring.ex
@@ -11,6 +11,14 @@ defmodule Poolex.Monitoring do
     {:ok, monitor_id}
   end
 
+  @spec stop(monitor_id()) :: :ok
+  @doc false
+  def stop(monitor_id) do
+    :ets.delete(monitor_id)
+
+    :ok
+  end
+
   @spec add(monitor_id(), pid(), kind_of_process()) :: :ok
   @doc false
   def add(monitor_id, process_pid, kind_of_process) do


Test patch:
diff --git a/test/poolex_test.exs b/test/poolex_test.exs
index da57ede..a41c603 100644
--- a/test/poolex_test.exs
+++ b/test/poolex_test.exs
@@ -372,6 +372,30 @@ defmodule PoolexTest do
     end
   end
 
+  describe "shutdown process" do
+    test "workers stop before the pool", %{pool_name: pool_name} do
+      {:ok, pool_pid} =
+        Poolex.start_link(pool_id: pool_name, worker_module: SomeWorker, workers_count: 1)
+
+      state = Poolex.get_state(pool_name)
+
+      supervisor_pid = state.supervisor
+      worker_pid = Poolex.run!(pool_name, fn pid -> pid end)
+
+      pool_monitor_ref = Process.monitor(pool_pid)
+      supervisor_monitor_ref = Process.monitor(supervisor_pid)
+      worker_monitor_ref = Process.monitor(worker_pid)
+
+      GenServer.stop(pool_name)
+
+      {:messages, [message_1, message_2, message_3]} = Process.info(self(), :messages)
+
+      assert message_1 == {:DOWN, worker_monitor_ref, :process, worker_pid, :shutdown}
+      assert message_2 == {:DOWN, supervisor_monitor_ref, :process, supervisor_pid, :normal}
+      assert message_3 == {:DOWN, pool_monitor_ref, :process, pool_pid, :normal}
+    end
+  end
+
   defp pool_name do
     1..10
     |> Enum.map(fn _ -> Enum.random(?a..?z) end)
Repository: general-CbIC/poolex
Pull request #55 (2023-07-31 07:29:59)

Fixed release of workers


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47fcba3..f7e04b3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,7 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ## [Unreleased]
 
-## [0.7.4] - 2023-07-23
+### Fixed
+
+- Fixed a serious bug when working with the `idle_workers` set. Previous version retired.
+
+## [0.7.4] - 2023-07-23 (RETIRED)
 
 ### Fixed
 
@@ -133,7 +137,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Fix links in hex documentation.
 - Added missing spec for `get_debug_info/1`.
 
-## [0.3.0] - 2023-02-03
+## [0.3.0] - 2023-02-03 (RETIRED)
 
 ### Added
 
diff --git a/lib/poolex.ex b/lib/poolex.ex
index 47a2067..e53255b 100644
--- a/lib/poolex.ex
+++ b/lib/poolex.ex
@@ -458,7 +458,7 @@ defmodule Poolex do
       | idle_workers_state:
           IdleWorkers.add(
             state.idle_workers_impl,
-            state.busy_workers_state,
+            state.idle_workers_state,
             worker
           )
     }


Test patch:
diff --git a/test/poolex_test.exs b/test/poolex_test.exs
index ebf3a37..472d168 100644
--- a/test/poolex_test.exs
+++ b/test/poolex_test.exs
@@ -41,6 +41,24 @@ defmodule PoolexTest do
       assert debug_info.waiting_callers_impl == SomeWaitingCallersImpl
     end
 
+    test "valid after using the worker" do
+      initial_fun = fn -> 0 end
+      pool_name = start_pool(worker_module: Agent, worker_args: [initial_fun], workers_count: 5)
+
+      {:ok, 0} = Poolex.run(pool_name, fn pid -> Agent.get(pid, & &1) end)
+
+      debug_info = Poolex.get_debug_info(pool_name)
+
+      assert debug_info.__struct__ == Poolex.DebugInfo
+      assert debug_info.busy_workers_count == 0
+      assert Enum.empty?(debug_info.busy_workers_pids)
+      assert debug_info.idle_workers_count == 5
+      assert Enum.count(debug_info.idle_workers_pids) == 5
+      assert debug_info.worker_module == Agent
+      assert debug_info.worker_args == [initial_fun]
+      assert debug_info.waiting_callers == []
+    end
+
     test "valid after holding some workers" do
       initial_fun = fn -> 0 end
       pool_name = start_pool(worker_module: Agent, worker_args: [initial_fun], workers_count: 5)
Repository: general-CbIC/poolex
Pull request #81 (2024-03-25 07:11:58)

Add `overflowed` boolean metric


Patch:
diff --git a/TODO.md b/TODO.md
index 40efb17..3ec5cd6 100644
--- a/TODO.md
+++ b/TODO.md
@@ -11,7 +11,7 @@ Using metrics, we see that typically, our application uses 10-20 processes, and
 - [ ] Pool size
   - [x] Idle workers count
   - [x] Busy workers count
-  - [ ] Is max_overflow used?
+  - [x] Is max_overflow used?
   - [ ] Maximum count of "overflowed" workers
 - [ ] Usage time
   - [ ] How long are workers busy?
diff --git a/lib/poolex/private/metrics.ex b/lib/poolex/private/metrics.ex
index 161ff89..53afc83 100644
--- a/lib/poolex/private/metrics.ex
+++ b/lib/poolex/private/metrics.ex
@@ -14,7 +14,8 @@ defmodule Poolex.Private.Metrics do
       [:poolex, :metrics, :pool_size],
       %{
         idle_workers_count: debug_info.idle_workers_count,
-        busy_workers_count: debug_info.busy_workers_count
+        busy_workers_count: debug_info.busy_workers_count,
+        overflowed: debug_info.overflow > 0
       },
       %{pool_id: pool_id}
     )


Test patch:
diff --git a/test/poolex_metrics_test.exs b/test/poolex_metrics_test.exs
index ec3f0e0..092ed57 100644
--- a/test/poolex_metrics_test.exs
+++ b/test/poolex_metrics_test.exs
@@ -7,11 +7,17 @@ defmodule PoolexMetricsTest do
 
   @tag telemetry_events: [[:poolex, :metrics, :pool_size]]
   test "pool size metrics" do
-    pool_id = start_pool(worker_module: SomeWorker, workers_count: 5, pool_size_metrics: true)
+    pool_id =
+      start_pool(
+        worker_module: SomeWorker,
+        workers_count: 5,
+        pool_size_metrics: true,
+        max_overflow: 5
+      )
 
     assert_telemetry_event(
       [:poolex, :metrics, :pool_size],
-      %{idle_workers_count: 5, busy_workers_count: 0},
+      %{idle_workers_count: 5, busy_workers_count: 0, overflowed: false},
       %{pool_id: ^pool_id}
     )
 
@@ -21,7 +27,19 @@ defmodule PoolexMetricsTest do
 
     assert_telemetry_event(
       [:poolex, :metrics, :pool_size],
-      %{idle_workers_count: 4},
+      %{idle_workers_count: 4, busy_workers_count: 1, overflowed: false},
+      %{pool_id: ^pool_id}
+    )
+
+    Enum.each(1..5, fn _ ->
+      launch_long_task(pool_id)
+    end)
+
+    Metrics.dispatch_pool_size_metrics(pool_id)
+
+    assert_telemetry_event(
+      [:poolex, :metrics, :pool_size],
+      %{idle_workers_count: 0, busy_workers_count: 6, overflowed: true},
       %{pool_id: ^pool_id}
     )
   end