I'm writing small utility app (JBoss Netty based) which should perform some trivial login against http requests.
Imagine an image buffer
private static byte[] image = DatatypeConverter.parseBase64Binary("...some base64 data here....");
private static final ChannelBuffer imageBuf = ChannelBuffers.wrappedBuffer(image);
So, the question is: Is it correct to share this imageBuf across multiple threads for writing? Or should I create the new one for each response?
Nope its not safe to share the ChannelBuffer accross Threads. ChannelBuffer's are not thread-safe
Related
I'm new to netty framework and I try to write netty server.
I have Handler in which constructor I pass a configuration (some parameters which may change while the server is running). The configuration must be updated (let's say every 10 minutes). What is the best way to do it?
I can change it in public void initChannel(SocketChannel ch); method but that seems like a bad idea to me.
Are there any built-in mechanisms to solve my problem?
I'm working on a greenfield reactive project where a lot of file handling IO is going on. Is it sufficient if I write the IO code in an imperative blocking manner and then wrap them in a Mono, publish them on boundedElastic scheduler? Will the boundedElastic pool size limit the number of concurrent operations?
If this is not the correct method, can you show an example how to write bytes to a file using Reactor?
Is it sufficient if I write the IO code in an imperative blocking manner and then wrap them in a Mono, publish them on boundedElastic scheduler?
This comes down to opinion on some level - but no, certainly not ideal not for a reactive greenfield project IMHO. boundedElastic() schedulers are great for interfacing with blocking IO when you must, but they're not a good replacement when a true non-blocking solution exists. (Sometimes this is a bit of a moot point with file handling, since it depends if it's possible for the underlying system to do it asynchronously - but usually that's possible these days.)
In your case, I'd look at wrapping AsynchronousFileChannel in a reactive publisher. You'll need to use create() or push() for this and then make explicit calls to the sink, but exactly how you do this depends on your use case. As a "simplest case" for file writing, you could feasibly do something like:
static Mono<Void> writeToFile(AsynchronousFileChannel channel, String content) {
return Mono.create(sink -> {
byte[] bytes = content.getBytes();
ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
buffer.put(bytes);
buffer.flip();
channel.write(buffer, 0, null, new CompletionHandler<>() {
#Override
public void completed(Integer result, Object attachment) {
sink.success();
}
#Override
public void failed(Throwable exc, Object attachment) {
sink.error(exc);
}
});
});
}
A more thorough / comprehensive example of bridging the two APIs can be found here - there's almost certainly others around also.
After some researching the java.nio and Spring library I have found the convenient approach to write strings to file as DataBuffers (which perfectly connect with WebFlux) into AsynchronousFileChannel using Spring classes.
It's not "truly" reactive way to write lines in file, but asyncronous and it is still better than using some standard blocking API.
public Mono<Void> writeRows(Flux<String> rowsFlux) {
DefaultDataBufferFactory bufferFactory = new DefaultDataBufferFactory();
CharSequenceEncoder encoder = CharSequenceEncoder.textPlainOnly();
Flux<DataBuffer> dataBufferFlux = rowsFlux.map(line ->
encoder.encodeValue(line, bufferFactory, ResolvableType.NONE, null, null)
);
return DataBufferUtils.write(
dataBufferFlux,
Path.of("/your_path_to_save_file/file.txt"),
StandardOpenOption.CREATE_NEW
);
}
Of course, for better performance in this case you can buffer your strings in flux and then append those strings to one string and create a data buffer from it.
Or if you already have Flux of data buffers you can write them to file using DataBufferUtils directly.
I've been using ZMQ in some Python applications for a while, but only very recently I decided to reimplement one of them in Go and I realized that ZMQ sockets are not thread-safe.
The original Python implementation uses an event loop that looks like this:
while running:
socks = dict(poller.poll(TIMEOUT))
if socks.get(router) == zmq.POLLIN:
client_id = router.recv()
_ = router.recv()
data = router.recv()
requests.append((client_id, data))
for req in requests:
rep = handle_request(req)
if rep:
replies.append(rep)
requests.remove(req)
for client_id, data in replies:
router.send(client_id, zmq.SNDMORE)
router.send(b'', zmq.SNDMORE)
router.send(data)
del replies[:]
The problem is that the reply might not be ready on the first pass, so whenever I have pending requests, I have to poll with a very short timeout or the clients will wait for more than they should, and the application ends up using a lot of CPU for polling.
When I decided to reimplement it in Go, I thought it would be as simple as this, avoiding the problem by using infinite timeout on polling:
for {
sockets, _ := poller.Poll(-1)
for _, socket := range sockets {
switch s := socket.Socket; s {
case router:
msg, _ := s.RecvMessage(0)
client_id := msg[0]
data := msg[2]
go handleRequest(router, client_id, data)
}
}
}
But that ideal implementation only works when I have a single client connected, or a light load. Under heavy load I get random assertion errors inside libzmq. I tried the following:
Following the zmq4 docs I tried adding a sync.Mutex and lock/unlock on all socket operations. It fails. I assume it's because ZMQ uses its own threads for flushing.
Creating one goroutine for polling/receiving and one for sending, and use channels in the same way I used the req/rep queues in the Python version. It fails, as I'm still sharing the socket.
Same as 2, but setting GOMAXPROCS=1. It fails, and throughput was very limited because replies were being held back until the Poll() call returned.
Use the req/rep channels as in 2, but use runtime.LockOSThread to keep all socket operations in the same thread as the socket. Has the same problem as above. It doesn't fail, but throughput was very limited.
Same as 4, but using the poll timeout strategy from the Python version. It works, but has the same problem the Python version does.
Share the context instead of the socket and create one socket for sending and one for receiving in separate goroutines, communicating with channels. It works, but I'll have to rewrite the client libs to use two sockets instead of one.
Get rid of zmq and use raw TCP sockets, which are thread-safe. It works perfectly, but I'll also have to rewrite the client libs.
So, it looks like 6 is how ZMQ was really intended to be used, as that's the only way I got it to work seamlessly with goroutines, but I wonder if there's any other way I haven't tried. Any ideas?
Update
With the answers here I realized I can just add an inproc PULL socket to the poller and have a goroutine connect and push a byte to break out of the infinite wait. It's not as versatile as the solutions suggested here, but it works and I can even backport it to the Python version.
I opened an issue a 1.5 years ago to introduce a port of https://github.com/vaughan0/go-zmq/blob/master/channels.go to pebbe/zmq4. Ultimately the author decided against it, but we have used this in production (under VERY heavy workloads) for a long time now.
This is a gist of the file that had to be added to the pebbe/zmq4 package (since it adds methods to the Socket). This could be re-written in such a way that the methods on the Socket receiver instead took a Socket as an argument, but since we vendor our code anyway, this was an easy way forward.
The basic usage is to create your Socket like normal (call it s for example) then you can:
channels := s.Channels()
outBound := channels.Out()
inBound := channels.In()
Now you have two channels of type [][]byte that you can use between goroutines, but a single goroutine - managed within the channels abstraction, is responsible for managing the Poller and communicating with the socket.
The blessed way to do this with pebbe/zmq4 is with a Reactor. Reactors have the ability to listen on Go channels, but you don't want to do that because they do so by polling the channel periodically using a poll timeout, which reintroduces the same exact problem you have in your Python version. Instead you can use zmq inproc sockets, with one end held by the reactor and the other end held by a goroutine that passes data in from a channel. It's complicated, verbose, and unpleasant, but I have used it successfully.
I have been using Rx for a while now for Events on my projects and dedicatedly for Socket programming and the good part is its doing well. Managing my code, performance advantage and much better to execute and interpret.
Lately I have to modify my project's process flow where i need to dump all the incoming data (from socket operations) into queues (using MSMQ implementation as decided for queueing).
As MSMQ provides async call for dequeing messages from the queue (but in an wierd pattern).
I have been struggling to use Rx for this purpose now, but enable to do so.
Question : Can some one give me a clean code example to implement Rx for message receiving from queue using Async pattern.
I need the async operator implementation for MSMQ analogous to something like this
var data = Observable.FromAsyncPattern<byte[]>(
this.receiverSocket.BeginReceive,
this.receiverSocket.EndReceive(some parameters);
Thanks in advance. *cheers* to Rx and .NET
It would be as simple as:
var queue = new System.Messaging.MessageQueue("test");
var fun = Observable.FromAsyncPattern((cb, obj) => queue.BeginReceive(TimeSpan.FromMinutes(10),obj,cb), a => queue.EndReceive(a));
var obs = fun();
I am creating a Firefox extension that allows using Standard ML (SML) as a client-side programming language in Firefox. The way it works is the following:
The extension launches a PolyML process (SML compiler with a top-level interactive shell).
A socket communication is then established between the extension and the PolyML process.
SML code is read from the webpage and is sent via the sockets to the PolyML process for evaluation.
That code may then use a library that I provide, for working with the DOM.
Here is how the DOM library is implemented:
Say someone executes an SML function DOM.getElementById
This request is forwarded via the sockets to the extension, where the extension executes the JavaScript function getElementById on the page and sends the result back to the PolyML process via the sockets.
My question is, in theory, what limits in terms of performance should I be expecting to have here, when it comes to the socket communication?
I did some very approximate profiling and it seems that using this interface between the extension and PolyML, I can approximately send 2500 messages/second, of an average size of 70 bytes/message.
To put this in more context, say I want to draw some animations in the browser using the Canvas element. If I want to achieve 20fps, that means I need to draw every frame in 0.05 seconds, which means I can only send around 125 messages per frame. Those messages correspond to JavaScript function calls. For example, the code below draws a path and is making 9 JavaScript function calls, that correspond to 9 messages in the socket communication.
val _ = Canvas.beginPath context;
val _ = Canvas.setFillStyle context fillColor;
val _ = Canvas.setStrokeStyle context fillColor;
val _ = Canvas.setLineWidth context size;
val _ = Canvas.moveTo context posx posy;
val _ = Canvas.lineTo context posx_new posy_new;
val _ = Canvas.stroke context;
val _ = Canvas.arc context posx_new posy_new (size/2.0) 0.0 6.28 true;
val _ = Canvas.fill context;
JavaScript, obviously, has a much better performance, I would imagine that you could make thousands (hundreds) of times of more Canvas/DOM function calls in those 0.05 seconds, for drawing a frame.
So, I guess my question is, do you have any experience with using socket communication for very rapid message interchange. I would like to know whether 2500 small messages / second (in this case, corresponding to 150 kbytes/second) seems about right or might I be doing something very wrong.
For example, one suspicion is that the socket implementation in firefox (in particular using it via the JavaScript interface https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsIServerSocket) is not very good for this kind of rapid interaction. For example, the reading from the socket is done via an event loop mechanism. That is I rely on Firefox.. to notify me about the availability of incoming socket messages and sometimes there is a large (e.g. 250ms) delay between sending the message and receiving it (though that seems to be happening only when firefox is busy with doing other things, and I'm more interested in the ..theoretical.. limits of the socket communication)
Any ideas, any thoughts, any flaws that you see? Do you think using other IPC mechanisms would be better, e.g. pipes, implementing my communication from C++ XPCOM component, rather than from JavaScript, foreign function interface to C (that both JavaScript and PolyML have)?
(The project is located at https://assembla.com/wiki/show/polymlext if anyone's interested)
TCP can be tuned for higher throughput or faster response time. For higher throughput, you need to set the socket buffer to larger value. For getting good response time with smaller chunk of data, you need to set the TCP_NODELAY socket option. TCP on loopback if its fine tuned it should be identical to any IPC mechanism. Newer windows OS does special optimization like increasing MTU size,etc on loopback adapter to make it faster.