Class: Daytona::PtyHandle

Inherits:
Object
  • Object
show all
Includes:
Observable
Defined in:
lib/daytona/common/pty.rb

Overview

rubocop:disable Metrics/ClassLength

Defined Under Namespace

Modules: Status, WebSocketControlStatus, WebSocketMessageType

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(websocket, session_id:, handle_resize: nil, handle_kill: nil) ⇒ PtyHandle

Initialize the PTY handle.

Parameters:

  • websocket (WebSocket::Client::Simple::Client)

    Connected WebSocket client connection

  • session_id (String)

    Session ID of the PTY session

  • handle_resize (Proc, nil) (defaults to: nil)

    Optional callback for resizing the PTY

  • handle_kill (Proc, nil) (defaults to: nil)

    Optional callback for killing the PTY



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/daytona/common/pty.rb', line 68

def initialize(websocket, session_id:, handle_resize: nil, handle_kill: nil)
  @websocket = websocket
  @session_id = session_id
  @handle_resize = handle_resize
  @handle_kill = handle_kill
  @exit_code = nil
  @error = nil
  @exited = false
  @logger = Sdk.logger

  @status = Status::INIT
  subscribe
end

Instance Attribute Details

#errorString? (readonly)

Returns Error message if the PTY failed.

Returns:

  • (String, nil)

    Error message if the PTY failed



60
61
62
# File 'lib/daytona/common/pty.rb', line 60

def error
  @error
end

#exit_codeInteger? (readonly)

Returns Exit code of the PTY process (if terminated).

Returns:

  • (Integer, nil)

    Exit code of the PTY process (if terminated)



57
58
59
# File 'lib/daytona/common/pty.rb', line 57

def exit_code
  @exit_code
end

#session_idString (readonly)

Returns Session ID of the PTY session.

Returns:

  • (String)

    Session ID of the PTY session



54
55
56
# File 'lib/daytona/common/pty.rb', line 54

def session_id
  @session_id
end

Instance Method Details

#connected?Boolean

Check if connected to the PTY session

A PTY that has exited is not usable even while the socket briefly stays open before the close frame, so treat it as disconnected.

Returns:

  • (Boolean)

    true if connected, false otherwise



87
# File 'lib/daytona/common/pty.rb', line 87

def connected? = websocket.open? && !@exited

#disconnectvoid

This method returns an undefined value.

Disconnect from the PTY session



171
# File 'lib/daytona/common/pty.rb', line 171

def disconnect = websocket.close

#each {|| ... } ⇒ void

This method returns an undefined value.

Yield Parameters:

  • (WebSocket::Frame::Data)


154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/daytona/common/pty.rb', line 154

def each(&)
  return unless block_given?

  queue = Queue.new
  add_observer(proc { queue << _1 }, :call)

  while websocket.open?
    drain(queue, &)
    sleep(SLEEP_INTERVAL)
  end

  drain(queue, &)
end

#killvoid

This method returns an undefined value.

Delete the PTY session

Raises:



127
128
129
130
131
# File 'lib/daytona/common/pty.rb', line 127

def kill
  raise Sdk::Error, 'No kill handler available' unless handle_kill

  handle_kill.call
end

#resize(pty_size) ⇒ DaytonaApiClient::PtySessionInfo

Resize the PTY terminal

Parameters:

  • pty_size (PtySize)

    New terminal size

Returns:

  • (DaytonaApiClient::PtySessionInfo)

    Updated PTY session information

Raises:



118
119
120
121
122
# File 'lib/daytona/common/pty.rb', line 118

def resize(pty_size)
  raise Sdk::Error, 'No resize handler available' unless handle_resize

  handle_resize.call(pty_size)
end

#send_input(input) ⇒ void

This method returns an undefined value.

Send input to the PTY session

Parameters:

  • input (String)

    Input to send to the PTY

Raises:



108
109
110
111
112
# File 'lib/daytona/common/pty.rb', line 108

def send_input(input)
  raise Sdk::Error, 'PTY session not connected' unless websocket.open?

  websocket.send(input)
end

#wait(timeout: nil, &on_data) ⇒ Daytona::PtyResult

Wait for the PTY session to complete

Parameters:

  • on_data (Proc, nil)

    Optional callback to handle output data

Returns:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/daytona/common/pty.rb', line 137

def wait(timeout: nil, &on_data) # rubocop:disable Metrics/CyclomaticComplexity,Metrics/AbcSize
  timeout ||= Float::INFINITY
  return PtyResult.new(exit_code:, error:) if @exited
  return unless status == Status::CONNECTED

  start_time = Time.now
  add_observer(on_data, :call) if on_data

  sleep(SLEEP_INTERVAL) while status == Status::CONNECTED && (Time.now - start_time) <= timeout

  PtyResult.new(exit_code:, error:)
ensure
  delete_observer(on_data) if on_data
end

#wait_for_connection(timeout: DEFAULT_TIMEOUT) ⇒ void

This method returns an undefined value.

Wait for the PTY connection to be established

Parameters:

  • timeout (Float) (defaults to: DEFAULT_TIMEOUT)

    Maximum time in seconds to wait for connection. Defaults to 10.0

Raises:



94
95
96
97
98
99
100
101
102
# File 'lib/daytona/common/pty.rb', line 94

def wait_for_connection(timeout: DEFAULT_TIMEOUT) # rubocop:disable Metrics/CyclomaticComplexity
  return if status == Status::CONNECTED || @exited

  start_time = Time.now

  sleep(SLEEP_INTERVAL) until status == Status::CONNECTED || @exited || (Time.now - start_time) > timeout

  raise Sdk::Error, 'PTY connection timeout' unless status == Status::CONNECTED || @exited
end