Skip to content

Commit

Permalink
fix: added runtime to FFI provider (#511)
Browse files Browse the repository at this point in the history
* added runtime to FFI provider
* added runtime to FFI Behavior
* fixed python example
  • Loading branch information
RyanKung authored Jan 1, 2024
1 parent 293036d commit e54f870
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 113 deletions.
20 changes: 14 additions & 6 deletions examples/ffi/rings.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ typedef struct Processor Processor;
*/
typedef struct InternalRpcHandler InternalRpcHandler;

typedef struct InternalRpcHandler InternalRpcHandler;

/**
* A wrapper for FFIbackendbehaviour, we needs runtime to make async request work
*/
typedef struct FFIBackendBehaviourWithRuntime FFIBackendBehaviourWithRuntime;


/**
* A structure to represent the Provider in a C-compatible format.
* This is necessary as using Arc directly in FFI can be unsafe.
Expand All @@ -29,15 +37,15 @@ typedef struct ProviderPtr {
* Context for handling backend behaviour
*/
typedef struct FFIBackendBehaviour {
void (**paintext_message_handler)(const struct FFIBackendBehaviour*,
void (**paintext_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*);
void (**service_message_handler)(const struct FFIBackendBehaviour*,
void (**service_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*);
void (**extension_message_handler)(const struct FFIBackendBehaviour*,
void (**extension_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*);
Expand All @@ -46,15 +54,15 @@ typedef struct FFIBackendBehaviour {
/**
* Backend behaviour for FFI
*/
struct FFIBackendBehaviour new_ffi_backend_behaviour(void (*paintext_message_handler)(const struct FFIBackendBehaviour*,
struct FFIBackendBehaviour new_ffi_backend_behaviour(void (*paintext_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*),
void (*service_message_handler)(const struct FFIBackendBehaviour*,
void (*service_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*),
void (*extension_message_handler)(const struct FFIBackendBehaviour*,
void (*extension_message_handler)(const struct FFIBackendBehaviourWithRuntime*,
const struct ProviderPtr*,
const char*,
const char*));
Expand Down
4 changes: 2 additions & 2 deletions examples/ffi/rings.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ def signer(msg, output):
return
return signer

@ffi.callback("void(*)(FFIBackendBehaviour *, ProviderPtr *, char *, char *)")
@ffi.callback("void(*)(FFIBackendBehaviourWithRuntime *, ProviderPtr *, char *, char *)")
def default_handler(ins, provider, relay, message):
return


@ffi.callback("void(*)(FFIBackendBehaviour *, ProviderPtr *, char *, char *)")
@ffi.callback("void(*)(FFIBackendBehaviourWithRuntime *, ProviderPtr *, char *, char *)")
def on_custom_message(ins, provider, relay, message):
print(message)
return
Expand Down
46 changes: 35 additions & 11 deletions node/src/backend/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,25 @@ use std::ffi::CString;
use std::sync::Arc;

use async_trait::async_trait;
use tokio::runtime::Runtime;

use crate::backend::types::BackendMessage;
use crate::backend::types::MessageHandler;
use crate::error::Result;
use crate::prelude::MessagePayload;
use crate::provider::ffi::ProviderPtr;
use crate::provider::ffi::ProviderWithRuntime;
use crate::provider::Provider;

/// Context for handling backend behaviour
/// cbindgen:no-export
#[repr(C)]
#[derive(Clone)]
pub struct FFIBackendBehaviour {
paintext_message_handler: Option<
Box<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
Expand All @@ -32,7 +35,7 @@ pub struct FFIBackendBehaviour {
service_message_handler: Option<
Box<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
Expand All @@ -42,7 +45,7 @@ pub struct FFIBackendBehaviour {
extension_message_handler: Option<
Box<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
Expand All @@ -51,28 +54,46 @@ pub struct FFIBackendBehaviour {
>,
}

/// A wrapper for FFIbackendbehaviour, we needs runtime to make async request work
/// cbindgen:field-names=[]
#[derive(Clone)]
pub struct FFIBackendBehaviourWithRuntime {
behaviour: FFIBackendBehaviour,
runtime: Arc<Runtime>,
}

impl FFIBackendBehaviourWithRuntime {
/// Create a new instance
pub fn new(behaviour: FFIBackendBehaviour, runtime: Arc<Runtime>) -> Self {
Self {
behaviour: behaviour.clone(),
runtime: runtime.clone(),
}
}
}

/// Backend behaviour for FFI
#[no_mangle]
pub extern "C" fn new_ffi_backend_behaviour(
paintext_message_handler: Option<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
) -> (),
>,
service_message_handler: Option<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
) -> (),
>,
extension_message_handler: Option<
extern "C" fn(
*const FFIBackendBehaviour,
*const FFIBackendBehaviourWithRuntime,
*const ProviderPtr,
*const c_char,
*const c_char,
Expand All @@ -88,15 +109,18 @@ pub extern "C" fn new_ffi_backend_behaviour(

macro_rules! handle_backend_message {
($self:ident, $provider:ident, $handler:ident, $payload: ident, $message:ident) => {
if let Some(handler) = &$self.$handler {
let provider: &Provider = Arc::as_ref(&$provider);
let provider_ptr: ProviderPtr = provider.into();
if let Some(handler) = &$self.behaviour.$handler {
let rt = $self.runtime.clone();

let provider_with_runtime = ProviderWithRuntime::new($provider.clone(), rt.clone());
provider_with_runtime.check_arc();
let provider_ptr: ProviderPtr = (&provider_with_runtime).into();
let payload = serde_json::to_string(&$payload)?;
let message = serde_json::to_string(&$message)?;
let payload = CString::new(payload)?;
let message = CString::new(message)?;
handler(
$self as *const FFIBackendBehaviour,
$self as *const FFIBackendBehaviourWithRuntime,
&provider_ptr as *const ProviderPtr,
payload.as_ptr(),
message.as_ptr(),
Expand All @@ -106,7 +130,7 @@ macro_rules! handle_backend_message {
}

#[async_trait]
impl MessageHandler<BackendMessage> for FFIBackendBehaviour {
impl MessageHandler<BackendMessage> for FFIBackendBehaviourWithRuntime {
async fn handle_message(
&self,
provider: Arc<Provider>,
Expand Down
Loading

0 comments on commit e54f870

Please sign in to comment.