Skip to content

Instantly share code, notes, and snippets.

@goswinr
Forked from deviousasti/Rpc.fs
Created August 23, 2022 15:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goswinr/ad840d497a6f18731be66b29348fd5b6 to your computer and use it in GitHub Desktop.
Save goswinr/ad840d497a6f18731be66b29348fd5b6 to your computer and use it in GitHub Desktop.
Fast inter-process RPC using shared memory
open SharedMemory
open MBrace.FsPickler
module Rpc =
type RpcContext<'command, 'message> =
{ name: string; buffer: RpcBuffer; post: 'command -> Async<'message>} with
interface IDisposable with
member this.Dispose() = this.buffer.Dispose()
let createHost name (handler : 'command -> Async<'message>) =
let pickler = FsPickler.CreateBinarySerializer()
let onReceive data = Async.StartAsTask <| async {
let command = pickler.UnPickle data
let! message = handler command
return pickler.Pickle message
}
{ name = name; buffer = new RpcBuffer(name, (fun _ data -> onReceive data)); post = handler }
let createClient name =
let pickler = FsPickler.CreateBinarySerializer()
let buffer = new RpcBuffer(name)
let onSend command = async {
let data = pickler.Pickle command
let! response = buffer.RemoteRequestAsync data |> Async.AwaitTask
if not response.Success then
failwith "Failed to get response"
return pickler.UnPickle response.Data
}
{ name = name; buffer = new RpcBuffer(name); post = onSend }
@goswinr
Copy link
Author

goswinr commented Aug 23, 2022

usage

type Command = Print of string | Clear | Scroll
type Message = OK | Fail

let handler cmd = async {
       return
           match cmd with 
           | Print text -> Console.WriteLine text; OK
           | Clear -> Console.Clear(); OK
           | _ -> Fail
   }

use host = Rpc.createHost "test-rpc" handler
use client = Rpc.createClient "test-rpc"            
let result: Message = client.post (Print "Hello") |> Async.RunSynchronously // Returns OK

https://twitter.com/deviousasti/status/1289247538319462400
I'll make do with this for now - to be replaced Fable.Remoting.Ipc someday. 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment