使用elysiajs,实现一个ffi运行在worker的a+b计算的接口

发布于:2024-04-28 ⋅ 阅读:(30) ⋅ 点赞:(0)

elysia是一个bunjs web框架,通过 Bun 运行时、静态代码分析和动态代码注入增效,成为性能最佳的 TypeScript 框架之一。可与 Go 和 Rust 相媲美,发展了快2年也是出了1.0稳定版本,bun现在也支持windows了,bun听说很快,让我来看看怎么个事。

话不多说直接开始,首先安装一下bunjs

# windows
powershell -c "irm bun.sh/install.ps1 | iex"

# mac & linux
curl -fsSL https://bun.sh/install | bash

然后使用bun create elysia app创建一个名为app的elysia项目,我这边同时安装一下prisma和eslint,如果不操作数据库,且不需要eslint那么则跳过当前部分,,eslint 由于不想配置,直接使用@antfu/eslint-config

bun add eslint @antfu/eslint-config

如果安装缓慢,在项目根目录创建bunfig.toml,为当前项目的bun设置淘宝镜像

[install]
registry = "https://registry.npmmirror.com/"

项目根目录创建eslint.config.mjs

// eslint.config.mjs
import antfu from '@antfu/eslint-config'

export default antfu()

安装swagger @elysiajs/swagger

这边我选择使用rust来对接,,直接找个空文件夹创建一个add.rs

// add.rs
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
    a + b
}

然后终端执行rustc --crate-type cdylib add.rs打包成插件给bun调用 将打包后的libadd文件放入elysia项目根目录新建文件夹libs下,/libs/libadd.dylib。

src下创建worker.ts文件,把下面代码复制进去

// /src/worker.ts
/* eslint-disable no-var */

import { FFIType, dlopen, suffix } from 'bun:ffi'

declare var self: Worker

const path = `libs/libadd.${suffix}`
const { symbols: {
  add,
} } = dlopen(path, {
  add: {
    args: [FFIType.int, FFIType.int],
    returns: FFIType.int,
  },
})

self.onmessage = (event: MessageEvent) => {
  const res = add(event.data.a, event.data.b)

  postMessage(res)
}

// /src/index
import { Elysia, t } from 'elysia'
import { swagger } from '@elysiajs/swagger'

const app = new Elysia()
app.use(
  swagger({
    provider: 'swagger-ui',
  }),
)

const worker = new Worker(new URL('worker.ts', import.meta.url).href)
function getWorker(a: number, b: number) {
  return new Promise<number>((resolve) => {
    worker.onmessage = (event) => {
      resolve(event.data)
    }
    worker.postMessage({
      a,
      b,
    })
  })
}
app.get('/add', async ({ query }) => {
  return getWorker(Number(query.a), Number(query.b))
}, {
  query: t.Object({
    a: t.Integer(),
    b: t.Integer(),
  }),
  response: t.Number(),
  transform({ query }) {
    query.a = Number(query.a)
    query.b = Number(query.b)
  },
})

app.listen(3000)

执行bun dev 运行项目,浏览器输入http://localhost:3000/swagger,就能看到swagger文档了

image.png

也是成功的运行成功了。

相关代码截图
/src/index.ts

image.png

/src/worker.ts image.png

写在最后,说一下,本人也是刚学一会,没多久,写个文章想问一下有没有交流群之类的,一起学习一下,对elysia和prisma还是挺感兴趣的,如果文章中哪里有问题欢迎及时指正。


网站公告

今日签到

点亮在社区的每一天
去签到