Ktor - Keep POST alive until receiving websocket communication - multithreading

I am building an API with Kotlin and Ktor that should be able to receive a normal POST request.
Upon receiving it, he should keep it alive and establish a series of asynchronous communications with other systems using websocket.
Only at the end of these communications and receiving certain information will it be able to respond to the POST request.
Needless to say, the request must be kept alive.
I'm not sure how to make this possible.
I have investigated using coroutines and threads but my inexperience prevents me from understanding what would be the best solution.

By default sequential code inside a coroutine is executed synchronously so you can just put your code for communication via Websockets inside a route's handler and in the end send a response. Here is an example:
import io.ktor.client.*
import io.ktor.client.engine.okhttp.*
import io.ktor.client.plugins.websocket.*
import io.ktor.client.plugins.websocket.WebSockets
import io.ktor.server.application.*
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
import io.ktor.server.websocket.*
import io.ktor.websocket.*
fun main() {
val client = HttpClient(OkHttp) {
install(WebSockets)
}
embeddedServer(Netty, port = 12345) {
routing {
get("/") {
client.webSocket("ws://127.0.0.1:5050/ws") {
outgoing.send(Frame.Text("Hello"))
val frame = incoming.receive()
println((frame as Frame.Text).readText())
println("Websockets is done")
}
call.respondText { "Done" }
}
}
}.start(wait = false)
embeddedServer(Netty, port = 5050) {
install(io.ktor.server.websocket.WebSockets)
routing {
webSocket("/ws") {
outgoing.send(Frame.Text("Hello from server"))
}
}
}.start()
}

Related

Unable to have multiple Subject listeners subscribed simultaneously in Angular

In Angular, I have two components that are listening to an RXJS Subject in a service. Both components are concurrently loaded, each in a separate tab.
My problem is that when the observable/subject is updated, only one of the event listeners get triggered. The one that does get triggered works as intended.
The subscriber, called in ngOnInit() (Its the same for both).
connectClear(){
this.sideBarService.clearEventChange
.subscribe((clearEvent)=> {
if(clearEvent)
{
if(this.previousSelected !== null){
this.previousSelected.classList.remove('selected')
for(let i=0;i<this.previousSelected.cells.length;i++){
this.previousSelected.cells[i].classList.remove('selection')
}
this.previousSelected = null
}
}
})}
The service:
clearEvent:boolean
clearEventChange:Subject<boolean> = new Subject<boolean>()
setClear(clearEvent:boolean){
this.clearEventChange.next(clearEvent)
}
constructor() {
this.clearEventChange.subscribe((value) => {
this.clearEvent = value
});
}
One idea that I'll try is to lazy load the tabs, so that only one component is loaded at a time, and then unsubscribe on ngOnDestroy, that way only one subscriber is connected at a time. That said, I am still curious if there is a way to connect multiple subscribers at once, or if I am just doing something wrong.
Maybe you run setClear() before the method connectClear() of the first component is initializated.
Check this:
Make sure you are using the same service (as singleton).
In order to do that, in the service decorator:
#injectable({ provideIn:'root})
Change the operator Subject for BehaviorSubject:
(remember to import BehaviorSubject instead import Subject).
clearEventChange:Subject<boolean> = new BehaviorSubject<boolean>(true);
It will trigger a true value (and hold the value until next activation of setClear()).
If everything is good, both subscribers should activate.

Changing State when Using Scala Concurrency

I have a function in my Controller that takes user input, and then, using an infinite loop, queries a database and sends the object returned from the database to a webpage. This all works fine, except that I needed to introduce concurrency in order to both run this logic and render the webpage.
The code is given by:
def getSearchResult = Action { request =>
val search = request.queryString.get("searchInput").head.head
val databaseSupport = new InteractWithDatabase(comm, db)
val put = Future {
while (true) {
val data = databaseSupport.getFromDatabase(search)
if (data.nonEmpty) {
if (data.head.vendorId.equals(search)) {
comm.communicator ! data.head
}
}
}
}
Ok(views.html.singleElement.render)
}
The issue arises when I want to call this again, but with a different input. Because the first thread is in an infinite loop, it never ceases to run and is still running even when I start the second thread. Therefore, both objects are being sent to the webpage at the same time in two separate threads.
How can I stop the first thread once I call this function again? Or, is there a better implementation of this whole idea so that I could do it without using multithreading?
Note: I tried removing the concurrency from this function (as multithreading has been the thing giving me all of these problems) and instead moving it to the web socket itself, but this posed problems as the web socket is connected to a router, and everything connects to the web socket through the router.
Try AsyncAction where you return a Future[Result] as a result. Make database call in side this result. E.g.(pseudo code),
def getSearchResult = AsyncAction { request =>
val search = request.queryString.get("searchInput").head.head
val databaseSupport = new InteractWithDatabase(comm, db)
Future {
val data = databaseSupport.getFromDatabase(search)
if (data.nonEmpty) {
if (data.head.vendorId.equals(search)) {
comm.communicator ! data.head // A
}
}
Ok(views.html.singleElement.render)
}
}
Better if databaseSupport.getFromDatabase(search) returns a Future but that is a story for another day. The tricky part is to figure how to deal with Actor at "A". Just remember at the exit it must return Future[Result] result type.

Scala client server multithreaded using socket

I cant get my head around this one here
I am a beginner to Scala just few weeks old and have tried but failed
I have read and tried about Actors, Futures,...etc didnt work for me
Could you supply a code of a server client example (or at least the server side)
Suppose to open connection using a socket that receives a string (i.e. file path) from several clients and process each one in a thread
import java.net.{Socket, ServerSocket}
import java.util.concurrent.{Executors, ExecutorService}
import java.util.Date
import java.io._
import scala.io._
import java.nio._
import java.util._
import scala.util.control.Breaks
import java.security.MessageDigest
import java.security.DigestInputStream
import scala.util.Sorting
class NetworkService(port: Int, poolSize: Int) extends Runnable {
val serverSocket = new ServerSocket(port)
val pool: ExecutorService = Executors.newFixedThreadPool(poolSize)
def run() {
try {
var i = 0
while (true) {
// This will block until a connection comes in.
val socket = serverSocket.accept()
val in = new BufferedReader(new InputStreamReader(socket.getInputStream)).readLine
/*var f = new FileSplit(in) //FileSplit is another class that i would like each
// client's sent string to be passed as an instance of
f.move*/
pool.execute(new Handler(socket))
}
} finally {
pool.shutdown()
}
}
}
class Handler(socket: Socket) extends Runnable {
def message = (Thread.currentThread.getName() + "\n").getBytes
def run() {
socket.getOutputStream.write(message)
socket.getOutputStream.close()
}
}
object MyServer {
def main(args: Array[String]) {
(new NetworkService(2030, 2)).run
}
}
You have several options available. You could do same old java style app, basically just using java standard libraries and scala syntax.
Maybe this helps: Scala equivalent of python echo server/client example?
You would just need to write logic that handles each socket (the one you get from accept()) in a new thread.
However I would not recommend using plain old java approach directly. There are great libraries out there that can handle that for you. For example Akka:
http://doc.akka.io/docs/akka/2.3.3/scala/io-tcp.html
I would also urge you to read about futures as they are super useful to do stuff async.

Correct usage of events in NodeJs - Concerning "this" context

I am designing a communication server in Node that handles incoming messages (sent by client1) and transfers them to someone else (client2), who answers the message and sends the answer back, via the server, to client1.
The communication happens via WebSockets, which implies an open connection from each client to the server.
Thus I implemented a ConnectionManager to which I can register any new connections when a new client comes online. Every connection gets assigned a messageQueue in which all incoming messages are cached before processing.
At the end of processing, I have a ServerTaskManager, who generates Output-Tasks for the server, telling him a message to send and a receiver to receive it.
This ServerTaskManager emits a Node-Event (inherits from EventEmitter) upon registering a new serverTask to which the server listens.
Now I would like my ConnectionManager to also listen to the event of the serverTaskManager, in order to make him push the next message in the messageQueue into processing.
Now the problem is, that I can catch the ServerTaskManager event within the ConnectionManager just fine, but, of course, the "this" within the listener is the ServerTaskManager, not the ConnectionManager. Thus calling any "this.someFunction()" functions that belong to the ConnectionManager won't work.
Here is some code:
/**
* ServerTaskManager - Constructor
* Implements Singleton pattern.
*/
function ServerTaskManager()
{
var __instance;
ServerTaskManager = function ServerTaskManager()
{
return __instance;
}
ServerTaskManager.prototype = this;
__instance = new ServerTaskManager();
__instance.constructor = ServerTaskManager;
return __instance;
}
util.inherits(ServerTaskManager, EventEmitter);
/**
* ConnectionManager - Constructor
* Also implements Singleton pattern.
*/
function ConnectionManager()
{
var __instance;
ConnectionManager = function ConnectionManager()
{
return __instance;
}
ConnectionManager.prototype = this;
__instance = new ConnectionManager();
__instance.constructor = ConnectionManager;
__instance.currentConnections = [];
// Listen for new serverInstructions on the serverTaskManager
serverTaskManager.on('newInstruction', function(messageObject, currentReceiver)
{
this.processNextMessage(currentReceiver);
});
return __instance;
}
util.inherits(ConnectionManager, EventEmitter);
Now when I run this and the "newInstructions" event is triggered by the serverTaskManager, node throws:
TypeError: Object #<ServerTaskManager> has no method 'processNextMessage'
Which is of course true. The function I want to call belongs to the ConnectionManager:
/**
* Starts processing the next message
*
* #param connectionId (int) - The ID of the connection, of which to process the next message.
*/
ConnectionManager.prototype.processNextMessage = function (connectionId)
{
// Some Code...
}
So obviously, when listening to the ServerTaskManager event, "this" within the listener is the ServerTaskManager. Now how do I call my ConnectionManager's function from within the listener?
I hope I am not completely misled by how events and listeners and/or prototypical extensions work (in Node). This project is by far the most advanced that I have worked on in JavaScript. Normally I am only coding PHP with a little bit of client side JS.
Thx in advance for any hints!
Worp
Like this.
serverTaskManager.on('newInstruction', function(messageObject, currentReceiver)
{
ConnectionManager.processNextMessage(currentReceiver);
});
Or like this.
serverTaskManager.on('newInstruction', function(messageObject, currentReceiver)
{
ConnectionManager().processNextMessage(currentReceiver);
});
PS: your question is unnecessarily long. When posting code, don't necessarily post your example. It is much easier to boil your code down to the simplest form that exhibits the behavior you are seeing. You'll get more quality responses this way.

How to use futures with Akka for asynchronous results

I am trying to write to multiple files concurrently using the Akka framework, First I created a class called MyWriter that writes to a file, then using futures I call the object twice hopping that 2 files will be created for me, but when I monitor the execusion of the program, it first populates the first file and then the second one (blocking /synchronously).
Q: how can I make the code bellow run (none-blocking /asynchronously)
import akka.actor._
import akka.dispatch._
import akka.pattern.ask
import akka.util.Timeout
import scala.concurrent.Await
import scala.concurrent.duration._
import scala.concurrent.Future
import scala.concurrent.{ ExecutionContext, Promise }
import ExecutionContext.Implicits.global
class my_controler {
}
object Main extends App {
val system = ActorSystem("HelloSystem")
val myobj = system.actorOf(Props(new MyWriter), name = "myobj")
implicit val timeout = Timeout(50 seconds)
val future2 = Future { myobj ! save("lots of conentet") }
val future1 = Future { myobj ! save("event more lots of conentet") }
}
the MyWriter code:
case class save(startval: String)
class MyWriter extends Actor {
def receive = {
case save(startval) => save_to_file(startval)
}
any ideas why the code does not execute concurrently?
Why are you wrapping the call to ? with an additional Future? Ask (?) returns a Future anyway, so what you are doing here is wrapping a Future around another Future and I'm not surte that's what you wanted to do.
The second issue I see is that you are sending two messages to the same actor instance and you are expecting them to be running in parallel. An actor instance processes its mailbox serially. If you wanted to process concurrently, then you will need two instances of your FileWriter actor to accomplish that. If that's all you want to do then just start up another instance of FileWriter and send it the second message.

Resources