Help On Kqueue Server

142 views
Skip to first unread message

Anto Aravinth

unread,
Mar 10, 2018, 4:19:47 AM3/10/18
to golang-nuts
Hello all, 

I'm learning golang and I wanted to try out this. Wanted to make a event driven server using Kqueue sys call (I'm on mac). A simple echo server will do. I started with the below code:

func main() {
var lis net.Listener
lis, err = net.Listen("tcp", "localhost:5000")

if err != nil {
fmt.Println(err)
}

p , err := syscall.Kqueue()
syscall.Kevent(p,
[]syscall.Kevent_t{{Ident: uint64(fd),
Flags: syscall.EV_ADD, Filter: syscall.EVFILT_READ}},
nil, nil)

}

Then later realized that, for attaching the READ for Kqueue, we need a file descriptor. I'm not sure on how to get the file descriptor from net package (may be net package does implements the same logic under the hood by calling out right syscalls for making event driven, but I wanted to try myself). 

Also, I wanted to know how to achieve the following:
1. Once I get my file descriptor, I wait for the events on the same using the appropriate sys calls for kqueue. Lets say a tcp client logs in, sends a request, I receive the event on my kqueue, now the thing I'm confused is that, how will I attach my kqueue logic to the opened tcp connection. From my understanding, usually sockes read/write using read/write syscalls, which are blocking call. Now using kqueue, we are making it more of event driven right? So how would I connect my kqueue with the socket to make it event driven? Any examples would be really great!


Thanks for your help. 


Doğan Kurt

unread,
Mar 10, 2018, 12:47:29 PM3/10/18
to golang-nuts
Go has goroutines -which makes network programming a lot easier- so that we don't have to deal with thread pools, epoll, kqueue or i/o completion ports.

Creating a goroutine per request is cheap, you should try this approach first and not optimize unless you're certain that goroutines are the cause of bottleneck.

Jesper Louis Andersen

unread,
Mar 11, 2018, 6:08:38 AM3/11/18
to Anto Aravinth, golang-nuts
On Sat, Mar 10, 2018 at 10:19 AM Anto Aravinth <anto.ara...@gmail.com> wrote:
Hello all, 

I'm learning golang and I wanted to try out this. Wanted to make a event driven server using Kqueue sys call (I'm on mac). A simple echo server will do.

If you want to learn this, I suggest you start off with something like C which the kqueue/kevent interface was built for. A Go-idiomatic solution would usually abstract this away by means of using goroutines[0].

Also, you code seems to be missing part of the usual socket interface. Calling net.Listen creates a Listener from which you can draw connections through the means of Accept(). You want the file descriptors of accepted sockets in your case I think.

In Go, an acceptor pool would usually spawn of goroutines which will then accept on the socket and do concurrent work. Note that there are many considerations in building a robust acceptor pool in general (and I would wager several exist of varying levels of stability).

[0] On Mac and BSD, the interface is usually kqueue/kevent. On Linux a completely different epoll() interface exist (which is a slightly bonkers API IMO), and on Illumos you have event ports filling in the same problem space.

Interestingly, systems such as Node.js is just a wrapper on top of these eventing systems, to which you've frankensteined in a Javascript JIT on the side. There are many limitations to such a system with regard to system stability and latency. Especially as projects grow large.

Reply all
Reply to author
Forward
0 new messages