Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plugin mechanism for compiled rust code #1984

Open
2 tasks
marcmo opened this issue Feb 12, 2024 · 2 comments
Open
2 tasks

Plugin mechanism for compiled rust code #1984

marcmo opened this issue Feb 12, 2024 · 2 comments
Assignees
Labels
native implemented in the rust part (natively)

Comments

@marcmo
Copy link
Member

marcmo commented Feb 12, 2024

we need to be able to link precompiled static libraries.

  • libs need to be pre-built for different architectures
  • should allow to pull in closed source functionality

First example will be the MDF library

@github-actions github-actions bot added the new newly created issue label Feb 12, 2024
@DmitryAstafyev
Copy link
Collaborator

DmitryAstafyev commented Feb 14, 2024

Tech Overview

Scripting Sockets Pipes Memory Wasm Dynamic lib (FFI) Static lib
Runtime loading
-1 - no; 1 - yes
1 1 1 1 1
Requires interpreter
or compiler
-1 - requires; 0 - doesn't
-1 0 0 0 0
Performance
estimation
(theoretically)
1 - poor; 5 - best
2 3 3 3 5
Windows
headache
0 - not expected
-1 - probably
0 -1 0 0 0
Possibility avoid cloning
1 - no cloning;
0 - partly;
-1- cloning
-1 -1 -1 1 1
Required rust unsafe
0 - yes;
1 - no;
1 1 1 1 0
Score 2 3 4 x 6 7 x
Disqualification R.0 R.1

R.0. - This feature heavily depends on the system’s kernel, so it may hurt the “Cross-Compatibility” requirement. [1]
R.1. - Requires compilation with basic application; no run-time loading

Plugins targets

  1. Source
  2. Parser

Requirements for plugins system

  • Setting/options of parser/source should be generic and represented as JSON object with the description of fields and types
  • Key-parser-traits should excluded into a standalone crate to be reused in the scope of a parser plugin

Plugin output files

  • lib's files
  • manifest file (with description, version etc in JSON or toml and with definition of plugin's type: (parser, source or...))

note: store in the home folder ~/.chipmunk/plugins

Loading

  • makes sense to load with chipmunk based on a list of active plugins from electron-layer

Opened questions

  • distribution? possible ways: manual (copying files), github repo based, server based etc.

Overview of ByteSource and Parser traits

Motivation to use (try to use) crate [abi_stable](https://github.com/rodrimati1992/abi_stable_crates) is better support of types. But in general would be good to understand, which types we would like to use and if is there a way to stay on the level of primitives.

ByteSource trait

pub trait ByteSource: Send + Sync {
    fn consume(&mut self, offset: usize);
    fn current_slice(&self) -> &[u8];                    <== Key method
    fn len(&self) -> usize;
    fn is_empty(&self) -> bool {
        self.len() == 0
    }
    async fn reload(&mut self, filter: Option<&SourceFilter>) -> Result<Option<ReloadInfo>, Error>;
    async fn cancel(&mut self) -> Result<(), Error> {
        Ok(())
    }
    async fn income(&mut self, _msg: sde::SdeRequest) -> Result<sde::SdeResponse, Error> {
        Err(Error::NotSupported)
    }
}

The key-method is current_slice, which delivers a byte's slice for future processing by a parser. Actually ByteSource plugin can operate with primitive types only.

Conclusion: plugin can operate just with primitive types

Parser trait


#[derive(Debug)]
pub enum ParseYield<T> {
    Message(T),
    Attachment(Attachment),
    MessageAndAttachment((T, Attachment)),
}

pub trait Parser<T> {
    fn parse<'a>(
        &mut self,
        input: &'a [u8],
        timestamp: Option<u64>,
    ) -> Result<(&'a [u8], Option<ParseYield<T>>), Error>;
}

#[derive(Debug, Clone, Serialize)]
pub struct Attachment {
    pub name: String,
    pub size: usize,
    pub created_date: Option<String>,
    pub modified_date: Option<String>,
    /// The indexes of the message within the original trace (0-based).
    pub messages: Vec<usize>,
    pub data: Vec<u8>,
}

  • as T we are using now LogMessage trait, which actually just inherit Display trait to convert bytes to a string. But this is only what we are doing always - converting LogMessage to string (always (!)). It means, to in current state we can just return from the plugin a string as bytes.
  • Attachment actually also is a collection of primitive types.
  • ParseYield can be represented as bytes using a simple own protocol (we can mark with the first byte a type of message and based on it parse in on a host)

Conclusion: plugin can operate just with primitive types in case of implementation our own simple protocol based on header and payload

References/links:

@DmitryAstafyev
Copy link
Collaborator

DmitryAstafyev commented Feb 14, 2024

As for the first step we could implement BinaryByteSource (sources/src/binary/raw.rs) as a plugin. For the first prototype:

  • hardcode path to plugin on rust level
  • one option - file path as a string
  • loading as soon as rust module is loaded
  • others as simple as possible

Goals:

  • confirm conception (possibility to use crate abi_stable)
  • check performance
  • check shutdown workflow
  • check possibility to operate with byte slices to avoid cloning

@marcmo marcmo added native implemented in the rust part (natively) and removed new newly created issue labels Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native implemented in the rust part (natively)
Projects
None yet
Development

No branches or pull requests

3 participants