Closed fabian-ahorner closed 5 years ago
Hey @wayrunner can you elaborate on why this is important to do? Holding open connections doesn't consume any resources within your application and there's already a heartbeat established in the underlying transport.
Hey, we are running the application on Heroku and are worried about the connection limit on their platform. We don't need subscriptions while the web app is in the foreground and rather close the socket to keep the number of connections low.
Hi @wayrunner,
Is there any reason you don't want to simply manage this concern within your app directly given you have access to the socket and you can simply choose to close it whenever you want ?
I would rather keep the core as lean as possible and use an HOC to deal with inactivity if that's needed / desirable.
@tlvenn I was having issues reopening the connection at a later stage. I found a solution using ApolloLink though that seems to be working well. Sorry for the pointless pull request 😅
import { ApolloLink } from 'apollo-link'
import Observable from 'zen-observable'
/**
* @example
* new InactivityWebSocketLink(socket, 5000, () => createAbsintheSocketLink(AbsintheSocket.create(socket)))
*/
export default class InactivityWebSocketLink extends ApolloLink {
activeConnections = 0
constructor (socket, inactivityTimeout, createLink) {
super()
this.socket = socket
this.timeout = null
this.inactivityTimeout = inactivityTimeout
this.createLink = createLink
this.link = createLink()
}
disconnect = () => {
this.socket.disconnect()
this.link = this.createLink()
}
request (operation, forward) {
this.activeConnections++
if (this.timeout) {
clearTimeout(this.timeout)
}
const next = this.link.request(operation, forward)
return new Observable(observer => {
const subscription = next.subscribe({
complete: observer.complete.bind(observer),
next: observer.next.bind(observer),
error: observer.complete.bind(observer)
})
return () => {
this.activeConnections--
if (this.activeConnections === 0) {
this.timeout = setTimeout(this.disconnect, this.inactivityTimeout)
}
if (subscription) subscription.unsubscribe()
}
})
}
}
This is inspired by the inactivityTimeout in https://github.com/apollographql/subscriptions-transport-ws. It will automatically close socket connection after a timeout if no subscriptions are active.
Given that there is no options passed in at the moment when creating a new absintheSocket, I was not sure if this is the best way of doing it. Please let me know if you want me to change this or move the implementation somewhere else.