Skip to content
This repository has been archived by the owner on Jul 8, 2022. It is now read-only.

RawSocketWebSocketClient.read() blocked Thread #50

Closed
lemkoleg opened this issue Mar 24, 2020 · 20 comments
Closed

RawSocketWebSocketClient.read() blocked Thread #50

lemkoleg opened this issue Mar 24, 2020 · 20 comments
Labels

Comments

@lemkoleg
Copy link

lemkoleg commented Mar 24, 2020

Hello. When I try to read data from a socket,
my thread freezes. (data comes in - that's for sure). Here is my code:

private suspend fun conn(connectionDNSName :String, connPort :Int){
val cl = createTcpClient()
cl.connect(connectionDNSName, connPort)
val mySocket = RawSocketWebSocketClient(
GlobalScope.coroutineContext, cl, URL.invoke(""), null, false, null, "")
//val r = MySocketChannel.readBinary() -- freezes
//val r = MySocketChannel..client.readAll() -- freezes
//val r = MySocketChannel..client.readAvailable() -- freezes

}

And one more question:
can I get RawSocketWebSocketClient from WebSocketClient ? For instance:
val url = "ws://hostname:3456"
val c: RawSocketWebSocketClient = WebSocketClient(url) as RawSocketWebSocketClient
And work with him as with RawSocketWebSocketClient.

@lemkoleg
Copy link
Author

I experimented and found that read functions do not return control when bytes in the socket end

@soywiz soywiz added the bug label Mar 25, 2020
@soywiz soywiz added this to Backlog in Korlibs via automation Mar 25, 2020
@soywiz soywiz moved this from Backlog to To do in Korlibs Mar 25, 2020
@lemkoleg
Copy link
Author

Hello. Tell me, are you planning to solve this problem? And when can you wait for a decision?

@soywiz soywiz moved this from To do to In progress in Korlibs Apr 15, 2020
@soywiz soywiz moved this from In progress to Current sprint in Korlibs Apr 15, 2020
@soywiz
Copy link
Collaborator

soywiz commented Apr 29, 2020

Yes, I want to fix this. Sorry for the delay. I have tons of bugs and issues reported and the amount of time I can invest is limited in my spare time. Contributions and PRs are welcome too. In the case nobody fixes it before me, I plan to do it ASAP. My current focus is on solving pending bugs. But I'm fixing first the ones directly related to Korge, so this will have to wait a bit more.
https://github.com/orgs/korlibs/projects/1

@lemkoleg
Copy link
Author

lemkoleg commented Apr 29, 2020 via email

@soywiz
Copy link
Collaborator

soywiz commented Apr 30, 2020

Nice, thanks! I would like to close all the remaining bugs before the end of the week, but since they are bugs the amount of time required is uncertain, but I will try 👍

@soywiz
Copy link
Collaborator

soywiz commented May 1, 2020

BTW. I have fixed the remaining issues already. In which platform do you have these blocks?
JVM, Android, Node.JS, K/N Windows, K/N Linux, K/N Mac, K/N iOS*?

@lemkoleg
Copy link
Author

lemkoleg commented May 1, 2020 via email

@lemkoleg
Copy link
Author

lemkoleg commented May 1, 2020 via email

@soywiz
Copy link
Collaborator

soywiz commented May 1, 2020

Then I'm going to close this issue.

Regarding to the problem you said. It is either a Kotlin.JS compiler problem or that you are calling it from the outside (JS) in a way that is not expected.
If you plan to call it from javascript. Consider not using a suspend fun (that internally requires a continuation as last parameter) but a normal function returning a Promise.
like:

@JsName("wait")
fun wait(t: Double) = GlobalScope.promise {
    delay(2000)
    console.log("this condition22")
}

Also you shouldn't use Long on the signature of the functions either, use Double instead and cast inside the body. Long in JS are not normal variables, but there is a wrapper that holds the long as two 32-bit integers.

@soywiz soywiz closed this as completed May 1, 2020
Korlibs automation moved this from Current sprint to Done May 1, 2020
@lemkoleg
Copy link
Author

lemkoleg commented May 1, 2020 via email

@lemkoleg
Copy link
Author

lemkoleg commented May 3, 2020 via email

@lemkoleg
Copy link
Author

lemkoleg commented May 3, 2020 via email

@soywiz
Copy link
Collaborator

soywiz commented May 4, 2020

The suspend functions internally in JVM and JS have a special signature like this:

suspend fun await(time: Long)

-->

function await(time, continuation)

If you don't provide the continuation, it is undefined, and thus the error. So it works as expected. Also Long in JS uses an internal class since JS doesn't have longs so you would have an additional error.
You can also put js("debugger;") and do step by step execution on the browser to understand this.

As said, if you plan to call it from javascript directly, your best bet is to return a promise instead that would be the equivalent to the suspend function (though in js, you have to use .then or use the await keyword)

Is it totally necessary for you to have the same code there for JS and JVM? You can use expect and actual to have different implementations while having the same interface. And you can expose additional methods like the one returning the promise in JS.
You can also make an:

expect MyPromise<T>...

With a actual typealias MyPromise<T> = Promise on JS, and an actual implementation on the JVM. Then return MyPromise in your cAwait method. You would have to call await or something on the JVM too to it actually suspends.
Depending on what you are trying to do in the end, there might be better ways to do this stuff than others.

@lemkoleg
Copy link
Author

lemkoleg commented May 4, 2020 via email

@soywiz
Copy link
Collaborator

soywiz commented May 4, 2020

The suspend implementation was not designed to be super interoperable, but to make code clean.
You can still create a continuation and pass it as last parameter.

You can also use this on the JS target:
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/promise.html

But think that Kotlin/common is not a panacea. Sometimes you have to write actual / expect declarations https://kotlinlang.org/docs/reference/platform-specific-declarations.html

What I can do if you want is to add a common Promise to Korio as I suggested in the previous comment so you can use it directly in common / all the targets.

I'll make a separate PR with that

@soywiz
Copy link
Collaborator

soywiz commented May 4, 2020

Here we are:
#68

you have to make your function to return Promise<T> then in JS you can use await waitFunc(10) and in plain Kotlin you can use waitFunc(10).await()

@soywiz
Copy link
Collaborator

soywiz commented May 4, 2020

Once deployed, Korio 1.11.1 includes the Promise class.

So the functions you need to use from JS, make them: fun myfunc(value: Double): Promise<T> and in javascript you can do await obj.myfunc(10) and in normal kotlin obj.myfunc(10).await() in a suspend function

7cd7274

@lemkoleg
Copy link
Author

lemkoleg commented May 4, 2020 via email

@soywiz
Copy link
Collaborator

soywiz commented May 4, 2020

Deploy is in progress: https://github.com/korlibs/korio/runs/644209072

If you want to try right now, you can download that commit and ./gradlew publishToMavenLocal

@lemkoleg
Copy link
Author

lemkoleg commented May 4, 2020 via email

@soywiz soywiz removed this from Done in Korlibs Jul 7, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants