-
Notifications
You must be signed in to change notification settings - Fork 106
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add socket messages callbacks and comms API
Fixes #366
- Loading branch information
Showing
22 changed files
with
690 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
117 changes: 117 additions & 0 deletions
117
jupyter-lib/api/src/main/kotlin/org/jetbrains/kotlinx/jupyter/api/libraries/connection.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package org.jetbrains.kotlinx.jupyter.api.libraries | ||
|
||
import kotlinx.serialization.json.Json | ||
import kotlinx.serialization.json.JsonElement | ||
import kotlinx.serialization.json.JsonObject | ||
import kotlinx.serialization.json.JsonPrimitive | ||
import kotlinx.serialization.json.decodeFromJsonElement | ||
import kotlinx.serialization.json.encodeToJsonElement | ||
import kotlinx.serialization.json.jsonObject | ||
import org.jetbrains.kotlinx.jupyter.util.emptyJsonObject | ||
|
||
enum class JupyterSocket { | ||
HB, | ||
SHELL, | ||
CONTROL, | ||
STDIN, | ||
IOPUB; | ||
} | ||
|
||
interface RawMessage { | ||
val id: List<ByteArray> | ||
val data: JsonElement | ||
} | ||
|
||
val RawMessage.header: JsonObject? | ||
get() { | ||
if (data !is JsonObject) return null | ||
val header = (data as JsonObject)["header"] | ||
|
||
if (header !is JsonObject) return null | ||
return header | ||
} | ||
|
||
val RawMessage.type: String? | ||
get() { | ||
val myHeader = header | ||
if (myHeader !is JsonObject) return null | ||
val type = myHeader["msg_type"] | ||
|
||
if (type !is JsonPrimitive || !type.isString) return null | ||
return type.content | ||
} | ||
|
||
val RawMessage.content: JsonObject? | ||
get() { | ||
if (data !is JsonObject) return null | ||
val content = (data as JsonObject)["content"] | ||
return (content as? JsonObject) | ||
} | ||
|
||
typealias CommOpenCallback = (Comm, JsonObject) -> Unit | ||
typealias CommMsgCallback = (JsonObject) -> Unit | ||
typealias CommCloseCallback = (JsonObject) -> Unit | ||
|
||
interface RawJupyterMessageCallback { | ||
val socket: JupyterSocket | ||
val messageType: String | ||
val action: (RawMessage) -> Unit | ||
} | ||
|
||
interface JupyterConnection { | ||
fun addCallback(callback: RawJupyterMessageCallback) | ||
fun removeCallback(callback: RawJupyterMessageCallback) | ||
fun send(socketName: JupyterSocket, message: RawMessage) | ||
fun send(socketName: JupyterSocket, parentMessage: RawMessage, type: String, content: JsonObject, metadata: JsonObject?) | ||
|
||
/** | ||
* Creates a comm with a given target, generates unique ID for it. Sends comm_open request to frontend | ||
* | ||
* @param target Target to create comm for. Should be registered on frontend side. | ||
* @param data Content of comm_open message | ||
* @return Created comm | ||
*/ | ||
fun openComm(target: String, data: JsonObject = emptyJsonObject): Comm | ||
|
||
/** | ||
* Closes a comm with a given ID. Sends comm_close request to frontend | ||
* | ||
* @param id ID of a comm to close | ||
* @param data Content of comm_close message | ||
*/ | ||
fun closeComm(id: String, data: JsonObject = emptyJsonObject) | ||
|
||
/** | ||
* Get all comms for a given target, or all opened comms if `target` is `null` | ||
*/ | ||
fun getComms(target: String? = null): Collection<Comm> | ||
fun registerTarget(target: String, callback: CommOpenCallback) | ||
} | ||
|
||
interface Comm { | ||
val target: String | ||
val id: String | ||
fun sendJson(data: JsonObject) | ||
fun onMessage(action: CommMsgCallback) | ||
fun onClose(action: CommCloseCallback) | ||
|
||
// Closes a comm. Sends comm_close request to frontend | ||
fun close(data: JsonObject = emptyJsonObject, notifyClient: Boolean = true) | ||
|
||
fun messageReceived(data: JsonObject) | ||
} | ||
|
||
/** | ||
* Send an object. `data` should be serializable to JSON object | ||
* (generally it means that the corresponding class should be marked with @Serializable) | ||
*/ | ||
inline fun <reified T> Comm.send(data: T) { | ||
sendJson(Json.encodeToJsonElement(data).jsonObject) | ||
} | ||
|
||
inline fun <reified T> Comm.onData(crossinline action: (T) -> Unit) { | ||
onMessage { json -> | ||
val data = Json.decodeFromJsonElement<T>(json) | ||
action(data) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.