I'm using Netty to write a client application that sends UDP messages to a server. In short I'm using this piece of code to write the stream to the channel:
ChannelFuture future = channel.write(request, remoteInetSocketAddress);
future.awaitUninterruptibly(timeout);
if(!future.isDone()){
//abort logic
}
Everything works fine, but one thing: I'm unable to test the abort logic as I cannot make the write to fail - i.e. even if the server is down the future would be completed successfully. The write operation usually takes about 1 ms so setting very little timeout doesn't help too much.
I know the preffered way would be to use an asynch model instead of await() call, however for my scenario I need it to be synchronous and I need to be sure it get finnished at some point.
Does anyone know how could I simulate an uncompleted future?
Many thanks in advance!
MM
Depending on how your code is written you could use a mock framework such as mockito. If that is not possible, you can also use a "connected" UDP socket, i.e. a datagram socket that is bound to a local address. If you send to a bogus server you should get PortunreachableException or something similar.
Netty has a class FailedFuture that can be used for the purpose of this,
You can for example mock your class with tests that simulate the following:
ChannelFuture future;
if(ALWAYS_FAIL) {
future = channel.newFailedFuture(new Exception("I failed"));
else
future = channel.write(request, remoteInetSocketAddress);
Related
Recently I was trying to implement simple web-socket application with Kotlin and ktor library. My server just has single web-socket handler which I implement like the following:
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
install(WebSockets)
routing {
webSocket("/handle") {
// ... more domain specific logic which uses coroutines ...
launch {
for (message in incoming) {
// process message
}
}
}
}
}
Original code contains more logic which include starting a bunch of another coroutines - so launch-ing the incoming queue processing in separate coroutine doesn't look weird for me.
Unfortunally, the ktor closes the underlying web-socket connection as soon, as inner block function finished. This was unexpected behaviour for me, because I though that webSocket function will behave similar to coroutineScope standard function, which waits for all attached coroutines to finish before continue execution.
This bug was very hard to spot for me, so I want to understand the design of webSocket function more deeply. So, I have the following questions:
Why webSocket function don't wait for attached coroutines? Is it a bug or a intentional decision?
What is the conventions about functions that deal with coroutineScope-s? Should I always guard my coroutines with known standard library functions (like coroutineScope)? Or should library writers follow some guidelines - for example, always wait for all attached coroutines in scope to finish?
This behavior was implemented long ago without structured concurrency in mind. I'd say it's a problem that can be fixed on the Ktor side so I've created this issue to address it. A fix will make it easier to write Websocket handlers and will improve readability.
It depends on whether library maintainers consider supporting structured concurrency or not for a particular case.
I'm starting with RX and I have a offline app the needs sync data with remote api. What better way to get data from database and send to remote api one by one watching the response of each? Which operators should I use to sequence tasks?
The simplest thing you can do is something like this (kotlin)
getDataFromDb()
.map { doNetworkRequest(it) }
.doOnNext { saveToDb(it) }
.subscribe()
but it really depends on your needs / environment.
You will probably need more mapping in the middle (e.g. to transform the network response to the data that you need to save to the db) and error handling.
Here I assume you don't need the result of saveToDb so I put it as a side effect instead of inside the main observable flow.
Another aspect is how you want to handle the network requests: is it ok to perform them in parallel or not? And maybe use a flatmap
We have an embedded Apache FTP server running in a gateway for several years. It always worked without problems.
But now a customer is trying to connect with a device of a brand that we've never had before, and contrary to all other clients so far, that thing sends the ALLO command in advance to make sure the server has enough space.
But Apache FTP doesn't seem to know that command. the trace log states:
RECEIVED: ALLO 77482
SENT: 502 Command ALLO not implemented.
following which the client cuts the connection.
The command is also not present in the Apache documentation:
https://mina.apache.org/ftpserver-project/ftpserver_commands.html
So the question is, can I plug my own implementation into the server somehow?
Just to be clear, I'm not asking how to implement the functionality. Just how I can pass my own implementation to Apache FTP for use. If that is possible without touching the source code.
Since the application in question has been running very stable for a long time, I would really hate to tear the Apache FTP server out of there and embed another one...
Well, that was surprisingly simple once I dug myself through to the right code.
The implementation of a command is simple enough, in this case I've just started with a stub for testing:
class ALLO : AbstractCommand() {
override fun execute(session: FtpIoSession, context: FtpServerContext, request: FtpRequest) {
session.write(LocalizedFtpReply.translate(session, request, context,
FtpReply.REPLY_200_COMMAND_OKAY, "ALLO", "bring it!"))
}
}
Inherit AbstractCommand, override execute and write a response to the session.
The question is of course then how to make the server aware of the implementation, which also turns out to be really simple, although there sure as hell doesn't seem to be any documentation around. But you can just instantiate a CommandFactoryFactory, map your implementation, build the CommandFactory and set it in the FtpServerFactory:
val commandFactoryFactory = CommandFactoryFactory()
commandFactoryFactory.addCommand("ALLO", ALLO())
serverFactory.commandFactory = commandFactoryFactory.createCommandFactory()
I have a GenServer, which is responsible for contacting an external resource. The result of calling external resource is not important, ever failures from time to time is acceptable, so using handle_cast seems appropriate for other parts of code. I do have an interface-like module for that external resource, and I'm using one GenServer to access the resource. So far so good.
But when I tried to write test for this gen_server, I couldn't figure out how to test the handle_cast. I have interface functions for GenServer, and I tried to test those ones, but they always return :ok, except when GenServer is not running. I could not test that.
I changed the code a bit. I abstracted the code in handle_cast into another function, and created a similar handle_call callback. Then I could test handle_call easily, but that was kind of a hack.
I would like to know how people generally test async code, like that. Was my approach correct, or acceptable? If not, what to do then?
The trick is to remember that a GenServer process handles messages one by one sequentially. This means we can make sure the process received and handled a message, by making sure it handled a message we sent later. This in turn means we can change any async operation into a synchronous one, by following it with a synchronisation message, for example some call.
The test scenario would look like this:
Issue asynchronous request.
Issue synchronous request and wait for the result.
Assert on the effects of the asynchronous request.
If the server doesn't have any suitable function for synchronisation, you can consider using :sys.get_state/2 - a call meant for debugging purposes, that is properly handled by all special processes (including GenServer) and is, what's probably the most important thing, synchronous. I'd consider it perfectly valid to use it for testing.
You can read more about other useful functions from the :sys module in GenServer documentation on debugging.
A cast request is of the form:
Module:handle_cast(Request, State) -> Result
Types:
Request = term()
State = term()
Result = {noreply,NewState} |
{noreply,NewState,Timeout} |
{noreply,NewState,hibernate} |
{stop,Reason,NewState}
NewState = term()
Timeout = int()>=0 | infinity
Reason = term()
so it is quite easy to perform unit test just calling it directly (no need to even start a server), providing a Request and a State, and asserting the returned Result. Of course it may also have some side effects (like writing in an ets table, modifying the process dictionary...) so you will need to initialize those resources before, and check the effect after the assert.
For example:
test_add() ->
{noreply,15} = my_counter:handle_cast({add,5},10).
I do asynchronous requests in LoadState method of a certain Page. I use HttpClient to make a request and I expect the splashscreen to go away while I await the result.
If I am not connected to any networks, the splashscreen immediately goes away and I get a blank page because the request obviously didn't happen.
But if I am connected to a network but have connectivity issues (for example, I set a wrong IP address) it seems to start a request and just block.
My expectation was that the HttpClient would realize that it cannot send a request and either throw an exception or just return something.
I managed to solve the issue of blocking by setting a timeout of around 800 milliseconds, but now it doesn't work properly when the Internet connection is ok. Is this the best solution, should I be setting the timeout at all? What is the timeout that's appropriate which would enable me to differentiate between an indefinitely blocking call and a proper call that's just on a slower network?
I could perhaps check for Internet connectivity before each request, but that sounds like an unpredictable solution...
EDIT: Now, it's really interesting. I have tried again, and it blocks at this point:
var rd = await httpClient.SendAsync(requestMsg);
If I use Task.Run() as suggested in the comments and get a new Thread, then it's always fine.
BUT it's also fine without Task.Run() if there is no Internet access but the network access is not "Limited" (it says that the IPv4 connectivity is "Internet access" although I cannot open a single website in a browser and no data is returned from the web service. It just throws System.Net.Http.HttpRequestException which was something I was expecting in the first place) Only blocks when the network connection is Limited.
What if instead of setting a timeout, you checked the connection status using
public static bool IsConnected
{
get
{
return NetworkInformation.GetInternetConnectionProfile() != null;
}
}
This way if IsConnected, then you make the call; otherwise, ignore it.
I'm not sure if you are running this in App.xaml.cs? I've found requests made in that class can be fickle and it may be best to move the functionality to an extended splash screen to ensure the application makes it all the way through the activation process.
http://msdn.microsoft.com/en-us/library/windows/apps/xaml/Hh868191(v=win.10).aspx