Comments (2)
Happy Halloween!
And now for the gruesome details.
To make messages reusable the whole API needs to change to pointers.
Also the direct access to the .Frames needs to be forbidden, because this and the attached frame data would be managed resources.
I experimented with a little slab allocator for frame data tied to Conn.read where the messages are created.
It already shows some reduction in allocations -- given my unscientific and crude measurement.
Actually I'm missing a point to attach the memory management to.
I'm old and missing the good old zmqContext. ;)
Having a context entity would allow the memory management be effective for all sockets in this context.
Given the asynchronous nature of the receive process a RecvInto(*Msg) seems not possible.
The actual reads are done in separate go routines and there is no way to pass the message to the reader who will receive the next message.
IMHO the reader should create the message without allocating everything as new and return a single pointer.
The default behaviour of messages should be the same as now. They will be gc'ed when they are not accessible any more.
A new method like Msg.Release() would recycle the internal storage of the message.
This would include the frame data (frame = []byte) and the associated container ([]frame).
I think keeping whole messages around would waste a lot of memory, because this would keep the
frame structure and data regardless of size.
So the public interface for receiving message could be:
type Socket interface {
Recv() (*Msg, error)
}
As like now Conn.read would create and populate a new message.
Instead of allocating every frame anew it would re-use already allocated frames.
This works nice for the NullSecurity case.
For the encryption case we're basically half-screwed. The original read of the frame data
is the same as for the unencrypted case.
But then we need to decrypt the data which results in a unknown size.
A simple optimization would be to request a slab size one increment larger as the
raw data. If this is not enough fall back to raw byte allocation.
After decryption the raw data can already be recycled.
The new message interface needs to be determined during the transition process.
A first try could be:
type Message interface {
// ownership is transferred to the message!
AppendFrames(frames ...[]byte) error
// ownership is still at the message!
Frame(i int) []byte
// Recycle all internal storage (frames etc.)
Release()
}
Hoping for a fruitful discussion.
Cheers
Guido
from zmq4.
when I "designed" go-zmq4, I had looked at various sources (rants about 0MQ from the original author, docs from nanomsg, etc...).
I don't recall the specifics but it seemed to me the general agreement was: "zmq_context_t
was a bad idea".
that said, it does seem like an obvious place were we to store a memory allocator.
we could shove it via yet another WithMemAllocator
func option.
wrt the AppendFrames
ownership transfer, even if there are precedents in Go (e.g.: values transferred over channels are supposed to also transfer ownership), it's not (if I am not mistaken) a very widely used API design.
but ok. we could start like that and see how it goes (changing from stealing to copying is less error prone than the other way around)
from zmq4.
Related Issues (20)
- pub sub err , when close the server the client get error and close HOT 1
- Go channel interface
- meta: consider setting up an OpenCollective account HOT 1
- router node restart recv block
- SUB socket SetOption must come after Dial, goczmq/pebbe don't have such limitation HOT 1
- Pull socket can not be properly closed, if no clients ever connected HOT 3
- REP socket races on client connection
- no reconnect possible when using `zmq4.NewPub` with `socket.Dial` HOT 4
- Why is go-zeromq/zmq4 not needing libzmq on windows? HOT 1
- socket accept a new connection, will send and read the greet message,if client always not response with greet message,other client can't connect to server
- Dead lock, how to fix? HOT 2
- github.com/pebbe/zmq2 (2.2.0) sub socket cannot connect to github.com/go-zeromq/zmq4 pub socket HOT 2
- Can't get a proxy to work (XSUB/XPUB)
- subSocket.Topics() is not accessible
- meta: new ZeroMQ/C++ license HOT 7
- Send timeout does not works HOT 4
- Deadlock detected by TestConnReaperDeadlock HOT 2
- PUB / SUB sockets
- PUB/SUB UDP socket HOT 1
- The connReaper goroutine may leak HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from zmq4.