Skip to content

Commit

Permalink
Also handle the Killed reason
Browse files Browse the repository at this point in the history
  • Loading branch information
sbergen committed Nov 28, 2024
1 parent 3e2b143 commit a510de5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 5 deletions.
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

## Unreleased

- Fixed a bug where using `actor.Stop(process.Abnormal(...))` would stop
the process with `Normal`.
- Fixed a bug where using `actor.Stop()` with other reasons than `Normal`
would stop the process with `Normal`.

## v0.14.1 - 2024-11-15

Expand Down
6 changes: 3 additions & 3 deletions src/gleam/otp/actor.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ import gleam/dynamic.{type Dynamic}
import gleam/erlang/atom
import gleam/erlang/charlist.{type Charlist}
import gleam/erlang/process.{
type ExitReason, type Pid, type Selector, type Subject, Abnormal,
type ExitReason, type Pid, type Selector, type Subject, Abnormal, Killed,
}
import gleam/option.{type Option, None, Some}
import gleam/otp/system.{
Expand Down Expand Up @@ -259,10 +259,10 @@ pub type Spec(state, msg) {
fn exit_process(reason: ExitReason) -> ExitReason {
case reason {
Abnormal(reason) -> process.send_abnormal_exit(process.self(), reason)
Killed -> process.kill(process.self())
_ -> Nil
}

// TODO
reason
}

Expand Down Expand Up @@ -409,7 +409,7 @@ fn initialise_actor(
loop(self)
}

// The init failed. Exit with an error.
// The init failed. Send the reason back to the parent, but exit normally.
Failed(reason) -> {
process.send(ack, Error(Abnormal(reason)))
exit_process(process.Normal)
Expand Down
22 changes: 22 additions & 0 deletions test/gleam/otp/actor_test.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,28 @@ pub fn abnormal_exit_can_be_trapped_test() {
)
}

pub fn killed_exit_can_be_trapped_test() {
process.trap_exits(True)
let exits =
process.new_selector()
|> process.selecting_trapped_exits(function.identity)

// Make an actor exit with a killed reason
let assert Ok(subject) =
actor.start(Nil, fn(_, _) { actor.Stop(process.Killed) })
process.send(subject, Nil)

let trapped_reason = process.select(exits, 10)

// Stop trapping exits, as otherwise other tests fail
process.trap_exits(False)

trapped_reason
|> should.equal(
Ok(process.ExitMessage(process.subject_owner(subject), process.Killed)),
)
}

fn mapped_selector(mapper: fn(a) -> ActorMessage) {
let subject = process.new_subject()

Expand Down

0 comments on commit a510de5

Please sign in to comment.