I want to establish a sse connection and use arrow...
# arrow
i
I want to establish a sse connection and use arrow: 1. it is not clear to me when i need to use a
Resource
or a
Bracket
2. Using bracket when the url is invalid for example
Copy code
bracketCase(
        acquire = { openConnection("<https://someURL>") },
        use = { connection ->
            connection.fetch()
        },
        release = { connection, exitCase ->
            when(exitCase) {
                is ExitCase.Completed -> println("Completed: $exitCase")
                is ExitCase.Cancelled -> println("Cancelled: $exitCase")
                is ExitCase.Failure ->
                    println("Failure: $exitCase")
            }
            println("Closing connection")
            closeConnection(connection)
        }
    )
i do get the exit case but i see the exception is still thrown.. What's the best way to handle the exception properly? do i need to wrap the computation with an
either
block?
Copy code
Failure: Failure(failure=java.net.UnknownHostException: someURL)
Closing connection
Exception in thread "main" java.net.UnknownHostException: someURL
	at java.base/sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:567)
	at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327)
	at java.base/java.net.Socket.connect(Socket.java:633)
	at java.base/sun.security.ssl.SSLSocketImpl.connect(SSLSocketImpl.java:304)
	at java.base/sun.security.ssl.BaseSSLSocketImpl.connect(BaseSSLSocketImpl.java:174)
finally since its a SSE connection do u think there are other things that need to be accounted for other than running the processing of the events in the Dispatchers.IO pool?
s
Hey @ipolyzos, I would always use
resource
, it's easier to understand with a simpler API and re-useable when you need it to be. There is no performance penalty for using
Resource
. This snippet with the current Alpha and 2.x.x is.
Copy code
resourceScope {
  val connection = install({ openConnection("<https://someURL>") }) { conn, exitCase ->
    log(exitCase)
    closeConnection(conn)
  }

  connection.fetch()
}
If you won't wan this to throw, you need to wrap it in
Either.catch
. Alternatively you can have
connection.fetch()
return
Either
and do.
Copy code
either {
  resourceScope {
    val conn = connection().bind()
    conn.fetch().bind()
  }
}
1.1.4-alpha.17 if you're okay using an alpha. It'll see a release in the next week or two
No, this and running it on
<http://Dispatchers.IO|Dispatchers.IO>
should be enough. Depending on how and where you run it using
SuspendApp
might be interesting. https://github.com/arrow-kt/suspendapp
i
Nice, will take a look 🙌 I'm trying to wrap my head around whats the best way to combine all the different types together. Like acquiring different resources, using them, handling their exceptions, combining with flow to handle streams. So expect more questions 😄
s
Happy to help!
Resource
composes pretty nicely with everything and you can use it's DSL if you create extension function on it.
Copy code
suspend fun ResourceScope.connection(url: String): Connection =
  install({ openConnection("<https://someURL>") }) { conn, exitCase ->
   log(exitCase, url)
   conn.close()
}
I implemented this in an example project yesterday, https://github.com/47deg/gh-alerts-subscriptions-kotlin/pull/46
i
i think this is exactly what i need.. gonna try out some stuff to see what works best.
s
If you need to stream resources, you're probably better of lifting them into
Flow
tbh so that you can just rely on the automatic back-pressure to keep them open. We have
Resource#asFlow
as well to do this 😉
i
ok so many cool resources.. need to grab them all together in one place, so its easy to find them.
s
I have more stuff lingering around 😅 Perhaps I should reference some of this stuff on my blog, so people can find it more easily 🤔