Hi Tiru, well, I'm not an expert, but as I understand it:
- All file I/O (on
Linux at least) is blocking,
i.e. "synchronous", meaning that code which uses it to read or
write to files (or networks or other I/O interfaces) "blocks" the
thread or process it's running in, so it can't do anything else
except wait until the I/O operation is completed.
- Non-blocking
("asynchronous") I/O works differently, by starting off the
operation and waiting to be called back (by a 'callback function')
with the result of the operation when it's completed. This enables
the process to carry on doing other things while waiting for the
I/O to finish.
- OpenResty is based on nginx, which uses non-blocking I/O, so
writing "blocking" code in either nginx modules or OpenResty Lua
modules would mean that the worker process it runs in would be
stuck until the I/O was finished.
- On a system with any kind of load, that would interfere with
the operation of the server, as other requests coming in would
have to wait until the code stopped blocking.
- If the blocking operation is something really fast, like
reading a very small file (that's likely cached by the OS anyway)
just once on connection startup, you might get away with this -
but generally speaking you don't want to be doing blocking I/O in
per-request code.
Hence my suggestion to store your configuration in a Lua module,
or by using the ngx.shared.DICT API, according to the docs at the
links I sent over before:
https://github.com/openresty/lua-nginx-module#data-sharing-within-an-nginx-worker
https://github.com/openresty/lua-nginx-module#ngxshareddict
Hope that helps.
Cheers,
Igor
Thanks Igor!
I managed to define the function in init_by_lua_block and
call it in preread_by_lua_block because writing to file is
not recommended as per the official docs.
I am not sure I understand the blocking IO part. Could you
kindly explain more or link to any docs?
On Saturday, November 18, 2017 at 12:49:38 AM UTC+5:30,
ti...@hasura.io wrote:
Hi all,
I am new to Lua and Openresty so I am not sure how to
go about this
I have a nginx conf which looks something like this:
stream {
upstream backend {
server 0.0.0.1:7777;
balancer_by_lua_block {
local balancer = require "ngx.balancer"
local ok, err = balancer.set_current_peer(ngx.ctx.hostip, ngx.ctx.port)
if not ok then
ngx.log(ngx.ERR, "failed to set the current
peer: ", ngx.ctx.hostip, ngx.ctx.port)
return ngx.exit(500)
end
}
}
server {
listen 12345;
preread_by_lua_block {
local ip = io.open("/tmp/ip1.lua", "r");
local body = ip:read "*a"
local hostip = string.gsub(body,"\n","")
ip:close()
ngx.ctx.hostip = hostip
ngx.ctx.port = ngx.var.server_port
}
proxy_pass backend;
}
server {
listen 12346;
preread_by_lua_block {
local ip = io.open("/tmp/ip2.lua", "r");
local body = ip:read "*a"
local hostip = string.gsub(body,"\n","")
ip:close()
ngx.ctx.hostip = hostip
ngx.ctx.port = ngx.var.server_port
}
proxy_pass backend;
}
Basically, I am load balancing across multiple servers
based on port but I need to resolve the IP from a dns
file. The dns files are different for each port.
There are lots of server blocks in reality. I don't
want to repeat the resolving logic in every server
block. How can I create a global function which takes as
argument the filename and returns the content of the
file?
.