Module: RubynCode::Protocols::ShutdownHandshake

Defined in:
lib/rubyn_code/protocols/shutdown_handshake.rb

Overview

Graceful shutdown protocol for agent teammates.

Implements a cooperative handshake where a coordinator requests shutdown and the target agent acknowledges after saving state.

Constant Summary collapse

TIMEOUT =

Default timeout in seconds when waiting for a shutdown response.

10

Class Method Summary collapse

Class Method Details

.graceful_shutdown(agent_name, mailbox:, session_persistence:, conversation:, requester: nil) ⇒ void

This method returns an undefined value.

Performs a full graceful shutdown for an agent: saves state, sends acknowledgement, and sets status to offline.

Parameters:

  • agent_name (String)

    the agent being shut down

  • mailbox (Teams::Mailbox)

    the team mailbox

  • session_persistence (#save_session)

    persistence layer for saving session state

  • conversation (Agent::Conversation)

    the agent’s conversation to persist

  • requester (String, nil) (defaults to: nil)

    the agent that requested shutdown (for acknowledgement)



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/rubyn_code/protocols/shutdown_handshake.rb', line 72

def graceful_shutdown(agent_name, mailbox:, session_persistence:, conversation:, requester: nil)
  # Step 1: Save current session state
  save_state(agent_name, session_persistence, conversation)

  # Step 2: Send shutdown acknowledgement if there is a requester
  respond(mailbox: mailbox, from: agent_name, to: requester, approve: true) if requester

  # Step 3: Broadcast offline status to all listeners
  mailbox.send(
    from: agent_name,
    to: '_system',
    content: "#{agent_name} is now offline",
    message_type: 'status_change'
  )
end

.initiate(mailbox:, from:, to:, timeout: TIMEOUT) ⇒ Symbol

Initiates a shutdown request to a teammate and waits for acknowledgement.

Parameters:

  • mailbox (Teams::Mailbox)

    the team mailbox

  • from (String)

    the requesting agent name

  • to (String)

    the target agent name to shut down

  • timeout (Integer) (defaults to: TIMEOUT)

    seconds to wait for response (default: 10)

Returns:

  • (Symbol)

    :acknowledged or :timeout



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rubyn_code/protocols/shutdown_handshake.rb', line 21

def initiate(mailbox:, from:, to:, timeout: TIMEOUT)
  mailbox.send(
    from: from,
    to: to,
    content: 'shutdown_request',
    message_type: 'shutdown_request'
  )

  deadline = Time.now + timeout

  loop do
    messages = mailbox.read_inbox(from)
    response = messages.find do |msg|
      msg[:from] == to && msg[:message_type] == 'shutdown_response'
    end

    return :acknowledged if response

    return :timeout if Time.now >= deadline

    sleep(0.25)
  end
end

.respond(mailbox:, from:, to:, approve: true) ⇒ String

Sends a shutdown response (approval or denial) from the target agent.

Parameters:

  • mailbox (Teams::Mailbox)

    the team mailbox

  • from (String)

    the responding agent name

  • to (String)

    the agent that requested the shutdown

  • approve (Boolean) (defaults to: true)

    whether to approve the shutdown (default: true)

Returns:

  • (String)

    the message id



52
53
54
55
56
57
58
59
60
61
# File 'lib/rubyn_code/protocols/shutdown_handshake.rb', line 52

def respond(mailbox:, from:, to:, approve: true)
  content = approve ? 'shutdown_approved' : 'shutdown_denied'

  mailbox.send(
    from: from,
    to: to,
    content: content,
    message_type: 'shutdown_response'
  )
end