From 0707d3099fd3b7b38706359675fe38d265b79f40 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Sun, 18 May 2025 09:43:32 -0400 Subject: [PATCH 1/6] add abnormal stop method --- src/gleam/otp/actor.gleam | 9 +++++++++ test/gleam/otp/actor_test.gleam | 26 +++++++++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/gleam/otp/actor.gleam b/src/gleam/otp/actor.gleam index 6065167..2e2241b 100644 --- a/src/gleam/otp/actor.gleam +++ b/src/gleam/otp/actor.gleam @@ -194,6 +194,15 @@ pub fn stop() -> Next(state, message) { Stop(process.Normal) } +/// Indicate the actor is in a bad state and should shut down. It will not +/// handle any new messages, and any linked processes will also exit abnormally. +/// +/// The provided reason will be given and propagated. +/// +pub fn stop_abnormal(reason: Dynamic) -> Next(state, message) { + Stop(process.Abnormal(reason)) +} + /// Provide a selector to change the messages that the actor is handling /// going forward. This replaces any selector that was previously given /// in the actor's `init` callback, or in any previous `Next` value. diff --git a/test/gleam/otp/actor_test.gleam b/test/gleam/otp/actor_test.gleam index 030ebd2..49505bd 100644 --- a/test/gleam/otp/actor_test.gleam +++ b/test/gleam/otp/actor_test.gleam @@ -265,7 +265,6 @@ pub fn abnormal_exit_can_be_trapped_test() { // Stop trapping exits, as otherwise other tests fail process.trap_exits(False) - // The weird reason below is because of https://github.com/gleam-lang/erlang/issues/66 trapped_reason |> should.equal( Ok(process.ExitMessage(actor.pid, process.Abnormal(dynamic.from("boo!")))), @@ -294,6 +293,31 @@ pub fn killed_exit_can_be_trapped_test() { |> should.equal(Ok(process.ExitMessage(actor.pid, process.Killed))) } +pub fn abnormal_stop_exits_linked_test() { + process.trap_exits(True) + let exits = + process.new_selector() + |> process.select_trapped_exits(function.identity) + + // Make an actor exit with an abnormal reason + let assert Ok(actor) = + actor.new(Nil) + |> actor.on_message(fn(_, _) { actor.stop_abnormal(dynamic.from("wibble")) }) + |> actor.start + + process.send(actor.data, "okay") + + let trapped_reason = process.selector_receive(exits, 10) + + // Stop trapping exits, as otherwise other tests fail + process.trap_exits(False) + + trapped_reason + |> should.equal( + Ok(process.ExitMessage(actor.pid, process.Abnormal(dynamic.from("wibble")))), + ) +} + fn mapped_selector( selector: process.Selector(ActorMessage), mapper: fn(a) -> ActorMessage, From 50a48a182412634e5f4a1c96afb87ed7c6a407b8 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Sun, 18 May 2025 09:44:50 -0400 Subject: [PATCH 2/6] changes --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 70e64f7..dd38e41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- The `actor` module gains a `stop_abnormal` method + ## v1.0.0-rc1 - 2025-05-16 - The `supervisor` module has been removed. From c9bb8598d5182035d98373dcf8bca7eec4b943c0 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Sun, 18 May 2025 09:47:11 -0400 Subject: [PATCH 3/6] hmm --- test/gleam/otp/actor_test.gleam | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/gleam/otp/actor_test.gleam b/test/gleam/otp/actor_test.gleam index 49505bd..9745d50 100644 --- a/test/gleam/otp/actor_test.gleam +++ b/test/gleam/otp/actor_test.gleam @@ -265,6 +265,7 @@ pub fn abnormal_exit_can_be_trapped_test() { // Stop trapping exits, as otherwise other tests fail process.trap_exits(False) + // The weird reason below is because of https://github.com/gleam-lang/erlang/issues/66 trapped_reason |> should.equal( Ok(process.ExitMessage(actor.pid, process.Abnormal(dynamic.from("boo!")))), @@ -312,6 +313,7 @@ pub fn abnormal_stop_exits_linked_test() { // Stop trapping exits, as otherwise other tests fail process.trap_exits(False) + // The weird reason below is because of https://github.com/gleam-lang/erlang/issues/66 trapped_reason |> should.equal( Ok(process.ExitMessage(actor.pid, process.Abnormal(dynamic.from("wibble")))), From 84cff883629203219f1c88ac623cd71d560656ab Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Sun, 18 May 2025 09:48:00 -0400 Subject: [PATCH 4/6] function not method --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd38e41..f5dc649 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## Unreleased -- The `actor` module gains a `stop_abnormal` method +- The `actor` module gains a `stop_abnormal` function ## v1.0.0-rc1 - 2025-05-16 From cf71fc203cd288c7642f36b9b20296961b132a65 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Wed, 21 May 2025 17:50:32 -0400 Subject: [PATCH 5/6] fixes --- src/gleam/otp/actor.gleam | 4 ++-- test/gleam/otp/actor_test.gleam | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gleam/otp/actor.gleam b/src/gleam/otp/actor.gleam index 2e2241b..38d3845 100644 --- a/src/gleam/otp/actor.gleam +++ b/src/gleam/otp/actor.gleam @@ -199,8 +199,8 @@ pub fn stop() -> Next(state, message) { /// /// The provided reason will be given and propagated. /// -pub fn stop_abnormal(reason: Dynamic) -> Next(state, message) { - Stop(process.Abnormal(reason)) +pub fn stop_abnormal(reason: String) -> Next(state, message) { + Stop(process.Abnormal(dynamic.string(reason))) } /// Provide a selector to change the messages that the actor is handling diff --git a/test/gleam/otp/actor_test.gleam b/test/gleam/otp/actor_test.gleam index 9745d50..adbadce 100644 --- a/test/gleam/otp/actor_test.gleam +++ b/test/gleam/otp/actor_test.gleam @@ -313,10 +313,12 @@ pub fn abnormal_stop_exits_linked_test() { // Stop trapping exits, as otherwise other tests fail process.trap_exits(False) - // The weird reason below is because of https://github.com/gleam-lang/erlang/issues/66 trapped_reason |> should.equal( - Ok(process.ExitMessage(actor.pid, process.Abnormal(dynamic.from("wibble")))), + Ok(process.ExitMessage( + actor.pid, + process.Abnormal(dynamic.string("wibble")), + )), ) } From 4348029bcab31832a313514fcbc6db123ca19225 Mon Sep 17 00:00:00 2001 From: Alex Manning Date: Sat, 24 May 2025 11:21:40 -0400 Subject: [PATCH 6/6] bump stdlib + remove test comment --- manifest.toml | 4 ++-- test/gleam/otp/actor_test.gleam | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/manifest.toml b/manifest.toml index bb464f8..5c5d924 100644 --- a/manifest.toml +++ b/manifest.toml @@ -3,8 +3,8 @@ packages = [ { name = "gleam_erlang", version = "1.0.0-rc1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "6E0CF4E1F66E2C9226B7554589544F00F12CE14858440EB1BF7EFDACDE1BBC64" }, - { name = "gleam_stdlib", version = "0.59.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "F8FEE9B35797301994B81AF75508CF87C328FE1585558B0FFD188DC2B32EAA95" }, - { name = "gleeunit", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "0E6C83834BA65EDCAAF4FE4FB94AC697D9262D83E6F58A750D63C9F6C8A9D9FF" }, + { name = "gleam_stdlib", version = "0.60.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "621D600BB134BC239CB2537630899817B1A42E60A1D46C5E9F3FAE39F88C800B" }, + { name = "gleeunit", version = "1.3.1", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleeunit", source = "hex", outer_checksum = "A7DD6C07B7DA49A6E28796058AA89E651D233B357D5607006D70619CD89DAAAB" }, { name = "logging", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "logging", source = "hex", outer_checksum = "1098FBF10B54B44C2C7FDF0B01C1253CAFACDACABEFB4B0D027803246753E06D" }, ] diff --git a/test/gleam/otp/actor_test.gleam b/test/gleam/otp/actor_test.gleam index adbadce..a25f478 100644 --- a/test/gleam/otp/actor_test.gleam +++ b/test/gleam/otp/actor_test.gleam @@ -303,7 +303,7 @@ pub fn abnormal_stop_exits_linked_test() { // Make an actor exit with an abnormal reason let assert Ok(actor) = actor.new(Nil) - |> actor.on_message(fn(_, _) { actor.stop_abnormal(dynamic.from("wibble")) }) + |> actor.on_message(fn(_, _) { actor.stop_abnormal("wibble") }) |> actor.start process.send(actor.data, "okay")