mailru / easygo Goto Github PK
View Code? Open in Web Editor NEWTools for building go apps.
License: MIT License
Tools for building go apps.
License: MIT License
I see in the implementation of epoll.wait() and kqueue.wait() you use a iterative way to execute all the callbacks, why not use goroutines to concurrently execute them for more effitiency? I'm just a little confused about it. If you don't think this is neccessary, please tell me why, I will be very thankful.
If I had more than one 'conn' to poll, then how will I know which 'conn' to read from CallbackFn(), if 'conn' was not defined as global?
Thanks
var closeBytes = []byte{1, 0, 0, 0, 0, 0, 0, 0} // what is this for?
// Close stops wait loop and closes all underlying resources.
func (ep *Epoll) Close() (err error) {
ep.mu.Lock()
{
if ep.closed {
ep.mu.Unlock()
return ErrClosed
}
ep.closed = true
if _, err = unix.Write(ep.eventFd, closeBytes); err != nil {
ep.mu.Unlock()
return
}
}
...
}
I'm currently trying to understand this repository. I don't understand the usage of the closeBytes.Is it used to close the eventFD?Is there any documetation about it?
I found a library https://github.com/mosn/pkg/tree/master/netpoll same as easygo.
c, err := l.Accept()
desc := netpoll.Must(netpoll.HandleRead(c))
poller.Start(desc, func(ev netpoll.Event) {
if ev&netpoll.EventHup != 0 || ev&netpoll.EventErr != 0 {
// close etc
}
go doSomething(c)
}
Why the code above doesn't "catch" connection error (eg. timeout)?
Also - when I close connection c inside doSomething(c) - the poller doesn't seem to catch that either - which leads me to a question - how to stop poller on error inside doSomething()?
Epoll has EPOLL_CLOEXEC and eventfd EFD_CLOEXEC to close socket after calling to exec syscall. While it is strange to be highload network server and call os.StartProcess or exec.Command at the same time, still better to provide this flags for consistency with Go runtime.
When you use conn.File(). It returns a duplicate file instead, as mentioned here. Docs say you need to close those files yourself, how do you handle that? And does it have any impact of open fd limit of os or any other side effects?
error : mailru\easygo\netpoll\handle.go:92: cannot use desc.fd() (type int) as type syscall.Handle in argument tosyscall.SetNonblock
you set non blocking here for handle read:
Lines 91 to 93 in 0c8322a
but on poller.Start(), the call to fd() would set underlying file to blocking mode again.
easygo/netpoll/netpoll_kqueue.go
Line 25 in 0c8322a
// Fd returns the integer Unix file descriptor referencing the open file.
// The file descriptor is valid only until f.Close is called or f is garbage collected.
// On Unix systems this will cause the SetDeadline methods to stop working.
func (f *File) Fd() uintptr {
if f == nil {
return ^(uintptr(0))
}
// If we put the file descriptor into nonblocking mode,
// then set it to blocking mode before we return it,
// because historically we have always returned a descriptor
// opened in blocking mode. The File will continue to work,
// but any blocking operation will tie up a thread.
if f.nonblock {
f.pfd.SetBlocking()
}
return uintptr(f.pfd.Sysfd)
}
This caused set deadliner doesn't work on conn owned by poller
if use tls.Listen(), netpoll.must Will fail,The reason for the failure is "could not get file descriptor", so support tls?
Script:
package main
import (
"fmt"
"io"
"log"
"net"
"github.com/gobwas/ws"
)
func HandleConn(conn net.Conn) {
for {
header, err := ws.ReadHeader(conn)
if err != nil {
log.Fatal(err)
}
buf := make([]byte, header.Length)
_, err = io.ReadFull(conn, buf)
if err != nil {
log.Fatal(err)
}
fmt.Println(buf)
fmt.Println(string(buf))
}
}
func main() {
ln, err := net.Listen("tcp", "localhost:8080")
if err != nil {
log.Fatal(err)
}
for {
conn, err := ln.Accept()
if err != nil {
log.Fatal(err)
}
_, err = ws.Upgrade(conn)
if err != nil {
log.Fatal(err)
}
go HandleConn(conn)
}
}
I do in browser console:
let socket = new WebSocket("ws://127.0.0.1:8080")
socket.send("Hello world")`
I see random bytes in the my terminal. Each call to socket.send("Hello world") return different bytes. But the length of the byte array is always equal to the length of the string. How can I fix this?
The OS independent type Poller
does not implement the Close
method that can be found in type Epoll
and Kqueue
(although) it isn't implemented for the last.
I am writing a Websocket tracker using gobwas/ws and this package, and I want to implement a graceful shutdown to my server. As of now, I am calling poller.Stop
on all Desc
then closing connections, but it represents alot of syscalls, being able to call Close
once would be easier and cleaner to stop the background loop.
Also, could you please consider implementing Close
for the Kqueue implementation ?
Thanks
I'm experimenting using netpoller with tls and websocket (github.com/gobwas/ws/wsutil), and I am concerned that with larger messages, the nonblocking socket read will return less than is needed to complete the websocket frame? From what I found via google search, nonblocking is only necessary when using level triggering, yet netpoll sets nonblocking on all connections.
do you see any problem with making setNonBlocking as optional and do you envision any issue with github.com/gobwas/ws/wsutil framing on top of netpoll
I'm new to Go and having to build this software in a hurry, so the copy/paste helps a lot! As I will need to do the same for my code, I've found the instructions for adding such examples to the godocs.
Also, THANK YOU for the trick to snag the file descriptor in your code! I was really upset when I didn't see a way to get it from the damn Go net library and thought I was going to just have to (further) hack the Go sources for my project. The Go language provides for some interesting idioms -- I'm still learning.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.