Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug] Subscriber closes after starting a server #43

Closed
IbrayevRamil opened this issue Feb 12, 2024 · 3 comments
Closed

[Bug] Subscriber closes after starting a server #43

IbrayevRamil opened this issue Feb 12, 2024 · 3 comments
Labels
bug Something isn't working

Comments

@IbrayevRamil
Copy link

Describe the bug

I've faced with an issue that zenoh subscribers are getting closed after starting a web-server (tried with spring-boot-tomcat, spring-boot-jetty, pure jetty).

You can use following simple code to reproduce it:

import io.zenoh.Config
import io.zenoh.Session
import io.zenoh.keyexpr.intoKeyExpr
import org.eclipse.jetty.server.Server

fun main(args: Array<String>) {
    val config = Config.Companion.from(
        """
            {
              "mode": "client",
              "connect": {
                "endpoints": ["tcp/localhost:7447"]
              }
            }
            """.trimIndent()
    )
    Session.open(config).fold(
        onSuccess = { session ->
            session.use {
                "test/test".intoKeyExpr().fold(
                    onSuccess = { keyExpr ->
                        keyExpr.use {
                            session.declareSubscriber(keyExpr)
                                .onClose { println("ON CLOSE CALLBACK IS CALLED") }
                                .reliable()
                                .with { println(String(it.value.payload)) }
                                .res()
                                .fold(
                                    onSuccess = { println("Successfully subscribed") },
                                    onFailure = { println("Failed to subscribe") }
                                )
                        }
                    },
                    onFailure = { println("Failed to get key expression") }
                )
            }
        },
        onFailure = { println("Failed to open session") }
    )
    Server(8080).apply {
        start()
        join()
    }
}

Seems like the issue not at jetty itself as different implementations of servers don't work, but in the way how servers threading lifecycle work.

Here are the logs:

Successfully subscribed
ON CLOSE CALLBACK IS CALLED
00:07:39.548 [main] INFO  org.eclipse.jetty.server.Server - jetty-12.0.6; built: 2024-01-30T02:43:24.387Z; git: 78ab6e6ba163f89cdd97f2ae0283fbb5e371cfaf; jvm 21.0.2+13-58
00:07:39.562 [main] INFO  o.e.jetty.server.AbstractConnector - Started ServerConnector@6d40861d{HTTP/1.1, (http/1.1)}{0.0.0.0:8080}
00:07:39.568 [main] INFO  org.eclipse.jetty.server.Server - Started oejs.Server@5acf93bb{STARTING}[12.0.6,sto=0] @1133ms

To reproduce

  1. Create subscriber
  2. Start server
  3. Subscriber is getting closed

System info

  • Zenoh: 0.10.1-rc
  • Jetty: 12.0.6
  • Kotlin: 1.9.22
  • Java: 21
  • CPU: Apple M3 Pro
@IbrayevRamil IbrayevRamil added the bug Something isn't working label Feb 12, 2024
@p-avital
Copy link
Contributor

This is not a bug at all: declared elements required state to be held not only locally, but in the Zenoh network as well.

This would mean failing to undeclare an element would cause resource leaks in the infrastructure. To avoid this, all Zenoh bindings that can support doing so use destructors.

This means that if you don't store your subscribers in some variable, they will instantly be destroyed (regardless of starting a server, which has nothing to do with the issue). In garbage collected languages, delays might appear, but eventual destruction is guaranteed.

I'm closing this issue and will open another to ensure @DariusIMP documents this behaviour a bit more to avoid future conditions about this.

@IbrayevRamil
Copy link
Author

IbrayevRamil commented Feb 12, 2024

This is not a bug at all: declared elements required state to be held not only locally, but in the Zenoh network as well.

This would mean failing to undeclare an element would cause resource leaks in the infrastructure. To avoid this, all Zenoh bindings that can support doing so use destructors.

This means that if you don't store your subscribers in some variable, they will instantly be destroyed (regardless of starting a server, which has nothing to do with the issue). In garbage collected languages, delays might appear, but eventual destruction is guaranteed.

I'm closing this issue and will open another to ensure @DariusIMP documents this behaviour a bit more to avoid future conditions about this.

Do you want to say that assigning Subscriber to a variable would resolve this issue?

@p-avital
Copy link
Contributor

Correct

DariusIMP added a commit to ZettaScaleLabs/zenoh-kotlin that referenced this issue May 14, 2024
…alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see eclipse-zenoh#43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.
DariusIMP added a commit to ZettaScaleLabs/zenoh-kotlin that referenced this issue Aug 1, 2024
…alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see eclipse-zenoh#43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.
DariusIMP added a commit to ZettaScaleLabs/zenoh-kotlin that referenced this issue Aug 1, 2024
…alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see eclipse-zenoh#43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.
gabrik pushed a commit that referenced this issue Aug 1, 2024
…sion. (#96)

* feat(background declarations): Allowing session declarations to stay alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see #43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.

* feat(background declarations): closing all session declarations immediately after doing `session.close()`
DariusIMP added a commit to ZettaScaleLabs/zenoh-kotlin that referenced this issue Aug 5, 2024
…sion. (eclipse-zenoh#96)

* feat(background declarations): Allowing session declarations to stay alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see eclipse-zenoh#43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.

* feat(background declarations): closing all session declarations immediately after doing `session.close()`
DariusIMP added a commit to ZettaScaleLabs/zenoh-kotlin that referenced this issue Aug 5, 2024
…sion. (eclipse-zenoh#96)

* feat(background declarations): Allowing session declarations to stay alive for the lifespan of a session.

Zenoh declarations ran for as long as the Kotlin variable representing them was kept alive. This
meant that whenever the user lost track of the variable, it got garbage collected and undeclared
in the process. This behavior seems to be counterintuitive for programmers used to garbage collected
languages (see eclipse-zenoh#43).

Therefore in this PR we provide the following change: we keep track of session declarations in a list
inside the session, allowing users to keep running them despite losing their references.
When the session is finalized, the associated declarations are undeclared.
In case the user needs to close a declaration earlier, they need to keep the variable in order
to undeclare it.

* feat(background declarations): closing all session declarations immediately after doing `session.close()`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants