a request-method in java that implements long-polling - multithreading

I have already written a request-method in java that sends a request to a simple Server. I have written this simple server and the Connection is based on sockets. When the server has the answer for the request, it will send it automatically to client. Now I want to write a new method that can behave as following:
if the server does not answer after a fixed period of time, then I send a new Request to the server using my request-method
My problem is to implement this idea. I am thinking in launching a thread, whenever the request-method is executed. If this thread does not hear something for fixed period of time, then the request method should be executed again. But how can I hear from the same socket used between that client and server?
I am also asking,if there is a simpler method that does not use threads
curently I am working on this idea
I am working on this idea:
1)send a request using my request-method
2)launch a thread for hearing from socket
3)If(no answer){ go to (1)}
else{
exit
}
I have some difficulties in step 3. How I can go to (1)

You may be able to accomplish this with a single thread using a SocketChannel and a Selector, see also these tutorials on SocketChannel and Selector. The gist of it is that you'll use long-polling on the Selector to let you know when your SocketChannel(s) are ready to read/write/etc using Selector#select(long timeout). (SocketChannel supports non-blocking, but from your problem description it sounds like things would be simpler using blocking)
SocketChannel socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("http://jenkov.com", 80));
Selector selector = Selector.open();
SelectionKey key = socketChannel.register(selector, SelectionKey.OP_READ);
// returns the number of channels ready after 5000ms; if you have
// multiple channels attached to the selector then you may prefer
// to iterate through the SelectionKeys
if(selector.select(5000) > 0) {
SocketChannel keyedChannel = (SocketChannel)key.channel();
// read/write the SocketChannel
} else {
// I think your best bet here is to close and reopen the Socket
// or to reinstantiate a new socket - depends on your Request method
}

I am working on this idea:
1)send a request using my request-method
2)launch a thread for hearing from socket
3)If(no answer) then go to (1)

Related

NestJS SSE memory leak

I want to use "Server Side Events" to notify all clients. I didn't find a way to do a broadcast, so I decided to use the Eventemitter internally. This causes a memory leak.
How can I broadcast or unsubscribe from the Eventemitter when the sse is broken (I think this is a bad solution)
My bad problem solution
thanks for asking a question on StackOverFlow!
NOTE: It would be better for the next time if you submit your code in text format instead of screenshot :)
Judging by the code you've provided, you are registering a new listener every time the Event is triggered by the server, which will trigger the event n^2 times of the events emitted.
You have 2 solutions which you can implement:
Check if 'channel.bindAccount' event is already registered and do not register again. I wouldn't recommend this solution but it can be done.
Register the event on your constructor and emit that in the sse. Example code:
constructor() {
const event = new Subject<MessageEvent>();
this.eventEmitter.on('channel.bindAccount', (payload) => {
console.log(payload);
event.next({data: payload} as MessageEvent);
});
}
#Public()
#Sse('event')
event(): Observable<MessageEvent> {
this.eventEmitter.emit('channel.bindAccount', (payload));
}
Registering the event in the constructor and emitting it on the sse is the idea, however I am not entirely sure where exactly payload comes from and I didn't test the code.

How can I simulate latency in Socket.io?

Currently, I'm testing my Node.js, Socket.io server on localhost and on devices connected to my router.
For testing purposes, I would like to simulate a delay in sending messages, so I know what it'll be like for users around the world.
Is there any effective way of doing this?
If it's the messages you send from the server that you want to delay, you can override the .emit() method on each new connection with one that adds a short delay. Here's one way of doing that on the server:
io.on('connection', function(socket) {
console.log("socket connected: ", socket.id);
// override the .emit() method
const emitFn = socket.emit
socket.emit = (...args) => setTimeout(() => {
emitFn.apply(socket, args)
}, 1000)
// rest of your connection handler here
});
Note, there is one caveat with this. If you pass an object or an array as the data for socket.emit(), you will see that this code does not make a copy of that data so the data will not be actually used until the data is sent (1 second from now). So, if the code doing the sending actually modifies that data before it is sent one second from now, that would likely create a problem. This could be fixed by making a copy of the incoming data, but I did not add that complexity here as it would not always be needed since it depends upon how the caller's code works.
An old but still popular question. :)
You can use either "iptables" or "tc" to simulate delays/dropped-packets. See the man page for "iptables" and look for 'statistic'. I suggest you make sure to specify the port or your ssh session will get affected.
Here are some good examples for "tc":
http://www.linuxfoundation.org/collaborate/workgroups/networking/netem

Is there any risk to read/write the same file content from different 'sessions' in Node JS?

I'm new in Node JS and i wonder if under mentioned snippets of code has multisession problem.
Consider I have Node JS server (express) and I listen on some POST request:
app.post('/sync/:method', onPostRequest);
var onPostRequest = function(req,res){
// parse request and fetch email list
var emails = [....]; // pseudocode
doJob(emails);
res.status(200).end('OK');
}
function doJob(_emails){
try {
emailsFromFile = fs.readFileSync(FILE_PATH, "utf8") || {};
if(_.isString(oldEmails)){
emailsFromFile = JSON.parse(emailsFromFile);
}
_emails.forEach(function(_email){
if( !emailsFromFile[_email] ){
emailsFromFile[_email] = 0;
}
else{
emailsFromFile[_email] += 1;
}
});
// write object back
fs.writeFileSync(FILE_PATH, JSON.stringify(emailsFromFile));
} catch (e) {
console.error(e);
};
}
So doJob method receives _emails list and I update (counter +1) these emails from object emailsFromFile loaded from file.
Consider I got 2 requests at the same time and it triggers doJob twice. I afraid that when one request loaded emailsFromFile from file, the second request might change file content.
Can anybody spread the light on this issue?
Because the code in the doJob() function is all synchronous, there is no risk of multiple requests causing a concurrency problem.
If you were using async IO in that function, then there would be possible concurrency issues.
To explain, Javascript in node.js is single threaded. So, there is only one thread of Javascript execution running at a time and that thread of execution runs until it returns back to the event loop. So, any sequence of entirely synchronous code like you have in doJob() will run to completion without interruption.
If, on the other hand, you use any asynchronous operations such as fs.readFile() instead of fs.readFileSync(), then that thread of execution will return back to the event loop at the point you call fs.readFileSync() and another request can be run while it is reading the file. If that were the case, then you could end up with two requests conflicting over the same file. In that case, you would have to implement some form of concurrency protection (some sort of flag or queue). This is the type of thing that databases offer lots of features for.
I have a node.js app running on a Raspberry Pi that uses lots of async file I/O and I can have conflicts with that code from multiple requests. I solved it by setting a flag anytime I'm writing to a specific file and any other requests that want to write to that file first check that flag and if it is set, those requests going into my own queue are then served when the prior request finishes its write operation. There are many other ways to solve that too. If this happens in a lot of places, then it's probably worth just getting a database that offers features for this type of write contention.

How to detect a REQ connect event to ROUTER

What I want?
Whenever the REQ connects with requester.connect() call to that host:port, ROUTER should detect this event and do something i.e. in this case cluster.fork();
I tried:
//Start Evented Child Node Processes alongwith a Request REQ Each
router.on("accept", function funcCB (fileDesc, endPt) {
//fire up a cluster fork for handling Requests
console.log("starting a new FORK process");
cluster.fork();
});
What router.on(<event>) should actually detect a
requester.connect()
??
As per this here these are the monitor events available for node zmq:
These are the triggered events as per the doc there:
connect - ZMQ_EVENT_CONNECTED
connect_delay - ZMQ_EVENT_CONNECT_DELAYED
connect_retry - ZMQ_EVENT_CONNECT_RETRIED
listen - ZMQ_EVENT_LISTENING
bind_error - ZMQ_EVENT_BIND_FAILED
accept - ZMQ_EVENT_ACCEPTED
accept_error - ZMQ_EVENT_ACCEPT_FAILED
close - ZMQ_EVENT_CLOSED
close_error - ZMQ_EVENT_CLOSE_FAILED
disconnect - ZMQ_EVENT_DISCONNECTED
How it works?
The beauty of ZeroMQ is in it's architecture. This means, the abstract scaleable archetype primitives ( PUB / SUB, PAIR, XREQ ) do exactly what these have been defined for.
The clean architecture separates I/O-thread(s) from socket's-entry-gate "behaviour" and keeps all the dirty stuff down there::
This said, it is of no use say I want ROUTER to detect and handle also this and that, if it was not defined to do this right in the ZeroMQ architecture.
How to do it?
The simplest approach to this and similar need is to design one's own composite element, let's for the simplicity sketch it as [[ROUTER]+[SUB]], where the node has both the [ROUTER]-trafic-oriented behaviour and also keeps a [SUB]-signalling-receiving behaviour, exposed to outer world via SUB.bind() at another host:portSIG
This way, remote processes REQ.connect( host:port) and PUB.connect( host:portSIG ) and operate on both the transport-plane and the signalling-plane as your design needs and implements.
ZeroMQ is a lovely can-do LEGO-toolbox.
Enjoy these powers.
So the answer was this small addition as posted by #Jason here on the SO comments section
//start the socket ROUTER monitor
router.monitor(500, 0);

What is the best architecture we can use for a Netty Client Application?

I need to develop a netty based Client, that accepts messages from a Notification Server, and places these messages as Http Requests to another Server in real time.
I have already coded a working application which does this, but I need to add multi-threading to this.
At this point, I am getting confused on how to handle Netty Channels inside a multi-threaded program, as I am all loaded with the conventional approach of sockets and threads.
When I tried to separate the Netty requesting part into a method, It complains about the Channels not being closed.
Can anyone guide me how to handle this?
I would like to use ExecutionHandler and OrderedMemoryAwareThreadPoolExecutor, but I am really new into this.
Help with some examples would be a real favour at this time.
Thanks in advance.
Just add an ExecutionHandler to the ChannelPipeline. This will make sure that every ChannelUpstreamHandler which is added behind the ExecutionHandler will get executed in an extra thread and so does not block the worker-thread.
Have you looked at the example code on the Netty site? The TelnetServer looks to do what you are talking about. The factory creates new handlers whenever it gets a connection. Threads from the Executors will be used whenever there is a new connection. You could use any thread pool and executor there I suspect:
// Configure the server.
ServerBootstrap bootstrap = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(), << change
Executors.newCachedThreadPool())); << change
// Configure the pipeline factory.
bootstrap.setPipelineFactory(new TelnetServerPipelineFactory());
// Bind and start to accept incoming connections.
bootstrap.bind(new InetSocketAddress(8080));
The TelnetServerHandler then handles the individual results.
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
// Cast to a String first.
// We know it is a String because we put some codec in TelnetPipelineFactory.
String request = (String) e.getMessage();
// Generate and write a response.
String response;
boolean close = false;
if (request.length() == 0) {
response = "Please type something.\r\n";
When the telnet is ready to close the connection it does this:
ChannelFuture future = e.getChannel().write(response);
if (close) {
future.addListener(ChannelFutureListener.CLOSE);
}

Resources