lua-users home
lua-l archive

Re: A Batteries API specification (was Re: LuaDEAL - Lua DEad Alive Libraries)

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


It was thus said that the Great pocomane once stated:
> On Tue, Jan 28, 2020 at 1:35 AM Sean Conner <sean@conman.org> wrote:
> > I don't have Windows, so I can't say for sure how Windows IOCP works, but
> > I'm hoping they can fit into the scheme I've outlined above. Thoughts?
> > Comments? Criticisms?
> >
> > -spc
> 
> I want to clarify a point: is this API proposed as a "Generic event"
> API (not just a "File/socket" one)? 
 Generally under POSIX, if it has a file handle, it can be used for event
processing. More and more modern POSIX systems are making non-file objects
available via file descriptors (like signals under Linux). Right now, I"m
aiming more for a "widely supported event processing" model, which now is
mostly file-related.
> I think that such API is crucial
> for the modularity, i.e. if I will write a C module that interact with
> a USB gamepad, I would like to put "Handler objects" in the same Set
> to monitor both gamepad and sockets contemporary.
 I know my current event library [2] can handle any file descriptor,
sockets, files, devices. 
> Without this, any modularity is illusionary.
> 
> I am not discussing the implementation here, if there is the need for
> a "Fake file descriptor" internally, it can be done [1]. In this
> spirit I would substitute "File descriptor" and "_tofd" with something
> else. 
 I'm open to suggestions. I don't like "_tofd" myself, but I'm not sure
what a better name would be. 
> I propose this also because the API should make sense in systems
> that do not use the file descriptor for event notification too, like
> windows.
 Agreed.
> Another comment: I have some doubt about the resulting event list.
> Probably events from different sources will be dispatched to different
> code, so the following format could be better (practically a mix of
> your own and the luaposix one):
> {
> [objA] = {
> read = true,
> write = false,
> ... -- all field always present
> }
> ... -- Object field is missing if there is no notification for it
> }
 I've found the propsed method (which is basically what I'm doing with my
current API) to be perfectly fine, and the Lua value I pass in is usually
(okay, always) a function. For instance, to accept connections via a TCP
socket:
	function listens(sock,mainf)
	 nfl.SOCKETS:insert(sock,'r',function() -- val here is a closure
	 local conn,remote,err = sock:accept()
	
	 if not conn then
	 syslog('error',"sock:accept() = %s",errno[err])
	 return
	 end
	
	 conn.nonblock = true
	 local ios,packet_handler = create_handler(conn,remote)
	 ios.__co = nfl.spawn(mainf,ios)
	 nfl.SOCKETS:insert(conn,'r',packet_handler) -- packet_handler is also a closure
	 end)
	
	 return sock
	end
 The function packet_handler deals with a normal two-way TCP socket, for
example (sans a bunch of unrelated details):
	-- conn is the socket
	-- remote is the remote address
	function create_handler(conn,remote)
	 local ios = mkios() -- this acts like a file: obj of Lua
	 return ios,function(event)
	 if event.read then
	 local _,packet,err = conn:recv()
	 -- deal with data
	 end
	 if event.write then
	 local bytes,err = conn:send(nil,buffer) -- don't need a remote address here, so it's nil
	 -- deal with partial writes, etc.
	 end
	 end
	end
 So I can easily deal with different events on different objects easily. 
In my gopher client for instance, I use the same event driver (even if it
was originally written with network services in mind) to deal with keyboard
input, so I can cancel network requests and such:
	 nfl.SOCKETS:insert(tty,"r",function()
	 syslog('debug',"attempting to cancel")
	 local c = tty.readchar()
	 if c == 'c_C' then
	 cancel()
	 end
	 end)
 The top level driver is written with this functionality in mind (example
sans a bunch of unrelated details):
	events = nfl.SOCKETS:events()
	for _,event in ipairs(events) do
	 event.obj(event)
	end
> Moreover, I think that keeping it simple is more valuable than your
> trick to substitute an optional var to Obj. If a user code really need
> it, it can keep the map in a table by its own.
 Honestly, I didn't find the current implementation all that difficult, and
I did it four different times (select(), poll(), epoll() and kqueue()). The
mechanism would have to exist *anyway* since what's referenced isn't the
underlying operating system file descriptor [3] but the higher level Lua
abstraction. The gory details can be seen here [2].
> [1] However, probably every lua-side standard specification will need
> some c-side specification. And probably, some internal details have to
> be exposed there.
 What did you have in mind?
 -spc
[2]	https://github.com/spc476/lua-conmanorg/blob/master/src/pollset.c
[3]	I know, I know, that's POSIX terminology, but I have no better at
	this time.

AltStyle によって変換されたページ (->オリジナル) /