作者:糖果

上一篇是用.so作为框架的库,这是接上回,用MoonScript实现库。

在HiLua工程中,创建/libs/moon目录,建立MoonScript库代码,如下:

HiLog.moon

class HiLog
    @log: =>
        print("HiLog...")
        return "HiLog..."

HiLog.lua

local HiLog
do
  local _class_0
  local _base_0 = { } 
  _base_0.__index = _base_0
  _class_0 = setmetatable({
    __init = function() end,
    __base = _base_0,
    __name = "HiLog"
  }, {
    __index = _base_0,
    __call = function(cls, ...)
      local _self_0 = setmetatable({}, _base_0)
      cls.__init(_self_0, ...)
      return _self_0
    end 
  })  
  _base_0.__class = _class_0
  local self = _class_0
  self.log = function(self)
    print("HiLog...")
    return "HiLog..."
  end 
  HiLog = _class_0
  return _class_0
end

创建新工程与app:

hi project Test-HiLua
hi app Test-HiLua

修改一下app.lua

require "log"
local HiLog = require "HiLog"
local Application = require "orc"
app = Application.new()

app:get("/hilua", function(request,id)
    ret = HiLog:log()   
    ngx.say(ret)
    ngx.say('hilua') 
end)

return app.run()

库可以用C写生成SO共享库,也可以用MoonScript翻译成Lua,然后与框架路由结合起 来,这种依赖就是纯调用依赖关联,尽量不产生数据关联。

原文地址:

源码地址:

作者:糖果

从Github上看,有一位叫做Dhaval Kapil老师完成了ElasticSearch for Lua的工作,另一位来自阿根廷的叫做Cristian Haunsen的老师,完成了ElasticSearch for Lapis的客户端程序写作工作,dhavalkapil还有一个博客可以访问:dhavalkapil.com

这次实验的目标,是测试一下本地直接运行ES for Lua,然后在Lapis中访问ES,我们的日志在ES,可以用Lua,也可以用Python完成ES的访问工作, Python没有问题,Lua就看这个实验了。

测试代码,如下:

local elasticsearch = require "elasticsearch"

local client = elasticsearch.client{
    hosts = {
      { -- Ignoring any of the following hosts parameters is allowed.
        -- The default shall be set
        protocol = "http",
        host = "localhost",
        port = 9200
      }
    },
    -- Optional parameters
    params = {
      pingTimeout = 2
    }
}

-- Will connect to default host/port
local client = elasticsearch.client()

local data, err = client:info()

Full list of params(全参数列表):

  1. pingTimeout : The timeout of a connection for ping and sniff request. Default is 1.
  2. selector : The type of selection strategy to be used. Default is RoundRobinSelector.
  3. connectionPool : The type of connection pool to be used. Default is StaticConnectionPool.
  4. connectionPoolSettings : The connection pool settings,
  5. maxRetryCount : The maximum times to retry if a particular connection fails.
  6. logLevel : The level of logging to be done. Default is warning.

Getting info of elasticsearch server(取得ES服务器信息)

local data, err = client:info()

Index a document(创建索引文档)

Everything is represented as a lua table.(一切皆为Lua Table)

local data, err = client:index{
  index = "my_index",
  type = "my_type",
  id = "my_doc",
  body = {
    my_key = "my_param"
  }
}

Get a document(取得文档)

data, err = client:get{
  index = "my_index",
  type = "my_type",
  id = "my_doc"
}

Delete a document(删除文档)

data, err = client:delete{
  index = "my_index",
  type = "my_type",
  id = "my_doc"
}

Searching a document (检索文档)

You can search a document using either query string:(使有查询字符进行检索)

data, err = client:search{
  index = "my_index",
  type = "my_type",
  q = "my_key:my_param"
}

Or either a request body:(或是请求体)

data, err = client:search{
  index = "my_index",
  type = "my_type",
  body = {
    query = {
      match = {
        my_key = "my_param"
      }
    }
  }
}

Update a document(更新文档)

data, err = client:update{
  index = "my_index",
  type = "my_type",
  id = "my_doc",
  body = {
    doc = {
      my_key = "new_param"
    }
  }
}

其实MoonScript for ElasticSearch的库是一个纯正的MoonScript实现,但从Readme中描述 是没显明的看是用MoonScript实现,不防抽出的MoonScript核心实现,贴出来看一下:

client = elasticsearch.client {
    hosts: config.elasticsearch.hosts and parse_hosts_config(config.elasticsearch.hosts) or {
        {
            protocol: "http"
            host: "127.0.0.1"
            port: 9200
        }
    },
    params: {
        -- Should return a table with { status, statusCode, body }
        preferred_engine: (method, uri, params, body, timeout) ->
            http = require "resty.http"
            httpc = http.new!
            args = { :method, :body, headers: { ["Content-Type"]: "application/json" } }
            res, err = httpc\request_uri(uri, args)

            if not res
                ngx.say("failed to request: ", err)
                return

            response = {}
            response.code = res.status
            response.statusCode = res.status
            response.body = res.body
            return response
    }
}
{
  :interpolate_query, :client
}

API封装以外,用的还是”resty.http”调用,这里有一个疑问,resty.http和simple.http是 不是同一个部件?

原文

lapis-elasticsearch

PS:本文测式用代码都来自至官方ES-LUA的Github的Readme。

作者:糖果

MoonScript调用Lapis的Simple.http,其实调用的就是OpenResty的http的接口。

candylab.moon

http = require "lapis.nginx.http"
body, status_code, headers = http.simple {
    url: 'http://moonscript.cn' 
    method: "GET"
    headers: {} 
}

candylab.lua

local http = require("lapis.nginx.http")
local body, status_code, headers = http.simple({
    url = 'http://moonscript.cn',
    method = "GET",
    headers = { }
})

所谓的Redis LUA客户端有两种版本,一种就是本地可运行版本,还有一个版本是OpenResty的版本,下面介绍的这段Moonscript段代码是本地版的。

作者:糖果

candylab.moon

redis = require "redis"
client = redis.connect '127.0.0.1', 6379

auth_flg = client\auth "www.moonscript.cn"

if not auth_flg 
    print("Auth NG!!!")

client\publish "chatroom", "www.candylab.net"

candylab.lua

local redis = require("redis")
local client = redis.connect('127.0.0.1', 6379)
local auth_flg = client:auth("www.moonscript.cn")
if not auth_flg then
  print("Auth NG!!!")
end
return client:publish("chatroom", "www.candylab.net")

作者:糖果

实际如果是直接调用ngx.timer的API,moonscript和lua的ngx.timer的函数写法差别不是很大。

candylab.moon

handler = (fill, params)->
    ok, err = ngx.timer.at(1, handler, "params-data")
    ngx.log(ngx.DEBUG, "ok:", ok, " err:", err)
         
ok, err = ngx.timer.at(6, handler, "params-data")
   
            
if not ok then
    ngx.log(ngx.ERR, "err:", err)

candylab.lua

local http = require("lapis.nginx.http")

local handler
handler = function(fill, params)
  local ok, err = ngx.timer.at(1, handler, "params-data")
  return ngx.log(ngx.DEBUG, "ok:", ok, " err:", err)
end

local ok, err = ngx.timer.at(6, handler, "params-data")

if not ok then
  return ngx.log(ngx.ERR, "err:", err)
end