Skip to content

Commit

Permalink
add rescue / panic when sending from non-owning ws process
Browse files Browse the repository at this point in the history
  • Loading branch information
rawhat committed May 16, 2024
1 parent 7c1e1e4 commit 34ac3c8
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 39 deletions.
46 changes: 36 additions & 10 deletions src/mist.gleam
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import gleam/bit_array
import gleam/bytes_builder.{type BytesBuilder}
import gleam/erlang.{rescue}
import gleam/erlang/process.{type ProcessDown, type Selector, type Subject}
import gleam/function
import gleam/http.{type Scheme, Http, Https} as gleam_http
Expand All @@ -18,6 +19,7 @@ import gleam/string_builder.{type StringBuilder}
import glisten
import glisten/transport
import gramps/websocket.{BinaryFrame, Data, TextFrame} as gramps_websocket
import logging
import mist/internal/buffer.{type Buffer, Buffer}
import mist/internal/encoder
import mist/internal/file
Expand Down Expand Up @@ -511,23 +513,47 @@ pub fn send_binary_frame(
connection: WebsocketConnection,
frame: BitArray,
) -> Result(Nil, glisten.SocketReason) {
process.try_call(
connection.self,
fn(reply) { websocket.Valid(websocket.SendBinary(frame, reply)) },
1000,
)
let binary_frame =
rescue(fn() {
gramps_websocket.to_binary_frame(frame, connection.deflate, None)
})
case binary_frame {
Ok(binary_frame) -> {
transport.send(connection.transport, connection.socket, binary_frame)
}
Error(reason) -> {
logging.log(
logging.Error,
"Cannot send messages from a different process than the WebSocket: "
<> string.inspect(reason),
)
panic as "Exiting while sending WebSocket message from non-owning process"
}
}
}

/// Sends a text frame across the websocket.
pub fn send_text_frame(
connection: WebsocketConnection,
frame: String,
) -> Result(Nil, glisten.SocketReason) {
process.try_call(
connection.self,
fn(reply) { websocket.Valid(websocket.SendText(frame, reply)) },
1000,
)
let text_frame =
rescue(fn() {
gramps_websocket.to_text_frame(frame, connection.deflate, None)
})
case text_frame {
Ok(text_frame) -> {
transport.send(connection.transport, connection.socket, text_frame)
}
Error(reason) -> {
logging.log(
logging.Error,
"Cannot send messages from a different process than the WebSocket: "
<> string.inspect(reason),
)
panic as "Exiting while sending WebSocket message from non-owning process"
}
}
}

// Returned by `init_server_sent_events`. This type must be passed to
Expand Down
30 changes: 1 addition & 29 deletions src/mist/internal/websocket.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ pub type ValidMessage(user_message) {
SocketMessage(BitArray)
SocketClosedMessage
UserMessage(user_message)
SendText(text: String, reply: Subject(Result(Nil, glisten.SocketReason)))
SendBinary(data: BitArray, reply: Subject(Result(Nil, glisten.SocketReason)))
}

pub type WebsocketMessage(user_message) {
Expand All @@ -33,7 +31,7 @@ pub type WebsocketConnection {
WebsocketConnection(
socket: Socket,
transport: Transport,
self: Subject(ValidMessage),
deflate: Option(Context),
)
}

Expand Down Expand Up @@ -133,32 +131,6 @@ pub fn initialize_connection(
}),
)
case msg {
Valid(SendText(text, reply)) -> {
let res =
text
|> websocket.to_text_frame(
option.map(state.permessage_deflate, fn(compression) {
compression.deflate
}),
None,
)
|> transport.send(connection.transport, connection.socket, _)
process.send(reply, res)
actor.continue(state)
}
Valid(SendBinary(data, reply)) -> {
let res =
data
|> websocket.to_binary_frame(
option.map(state.permessage_deflate, fn(compression) {
compression.deflate
}),
None,
)
|> transport.send(connection.transport, connection.socket, _)
process.send(reply, res)
actor.continue(state)
}
Valid(SocketMessage(data)) -> {
let #(frames, rest) =
get_messages(
Expand Down

0 comments on commit 34ac3c8

Please sign in to comment.