Skip to content

ailua is lua nif which is inspired by elua for production from ailink.io

License

Notifications You must be signed in to change notification settings

DavidAlphaFox/ailua

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ailua

使用lua作为Erlang的业务插件,用来处理一些配置性的变化,支持非调度器线程池来执行lua。ailua使用的是nif模式直接内嵌到Erlang的虚拟机中,如果lua代码过于复杂的话造成崩溃或内存泄漏, 则会引起Erlang虚拟机崩溃和内存泄漏

依赖

因为lua需要readline这个库,所以需要预先安装readline开发库。

lua版本

master分支,使用的是lua5.3版本,使用的默认配置,并未使用erlang的内存分配器优化lua的内存分配

luajit分支,使用的是luajit-2.0.5版本,默认打开jit模式,支持lua5.1版本的语法

线程池规则

最少为1个线程,默认会创建Erlang调度器线程的数量一半新线程作为异步线程池,目前不 支持指定线程数量的方法。

注意

ailua 从tag-0.3.0及tag-0.3.0-jit后就不再支持线程池,改为使用Erlang自身的Dirty Schedules来做承载,可以配合poolboy或者 ailib中的pool相关模块使用

如何使用

创建

{ok,Ref} = ailua:new()
带有初始化路径
{ok,CWD} = file:get_cwd(),
P = erlang:list_to_binary(filename:join(CWD,"./?.lua")),
{ok,Ref} = ailua:new(<<";",P/binary>>).

Ref会绑定一个lua虚拟机,该Ref会随着创建进程的退出而释放
创建Ref的Erlang进程崩溃后,该Ref的行为如下

  • 如果该Ref有异步操作,会在最后一个异步操作后释放该Ref绑定的lua虚拟机
  • 如果该Ref没有任何异步操作,则立刻释放该Ref绑定的lua虚拟机

加载lua文件

同步方法
ok = ailua:dofile(Ref,FileName)

异步方法
CallerRef = make_ref(),
CallerPid = self(),
ok = ailua:dofile_async(L,CallerRef,CallerPid,FileName)

执行lua函数

同步方法
ok = ailua:call(Ref,FunctionName,Args)

异步方法
CallerRef = make_ref(),
CallerPid = self(),
ok = ailua:async_call(L,CallerRef,CallerPid,FunctionName,Args)

其中FunctionName为字符串,Arags为列表

注意事项

  • lua脚本需要使用绝对路径,如果想使用相对路径,需要自己设置lua的package相关路径
  • 目前Erlang到lua传值不支持tuple和proplists,不支持Erlang高阶函数传入lua
  • Erlang到lua传值,字符串使用binary而非list
  • Erlang到lua传值,如果字符串是list,则会被映射到lua的table上
  • Erlang到lua传值,原子值true,false会自动转化成lua的boolean型,undefined和null会自动转化成lua的nil值
  • Erlang到lua传值,如果整形大于了18446744073709551615,默认方法会将该整形转化成double
  • Erlang到lua传值,如果整形小于了-9223372036854775808,默认方法会将该整形转化成double
  • lua到Erlang传值,boolean会自动变更为atom,nil会自动变更为erlang的undefined
  • lua表的元表中请勿设置_ERL_MAP为true字段,该字段是ailua用来区分lua回传给Erlang的table是list还是map
  • lua回传map的时候,请使用to_erl_map(map)来进行转化
  • 目前不支持lua的userdata,function等比较特殊类型
  • 请避免在lua脚本中执行print操作,ailua并为处理lua的输出,这些输出会直接输出到stderr上
  • 不建议使用lua带so的依赖,不建议使用外部IO和lua的协作线程

例子

ailua并未附带过多例子,但是仍有一个test.lua来进行测试

执行方式如下

make 
erl -pa ./ebin

{ok,Ref} = ailua:new().
ok = ailua:dofile(Ref,"./test/test.lua").
ailua:call(Ref,"hi",[#{1 => "hi"}]).
ailua:call(Ref,"test:in_table",[1]).
ailua:call(Ref,"test.in_table2",[2]).