Comments (4)
I got a chance to look at this. I was able to resolve this at the RedisClient level. I did the following
- In RedisClient -> Send
- Store the promise when it is created
- Note I used a dictionary since the array "removeObject" is now a pain in Swift
- Remove the promise when it is fulfilled (future.always)
- Store the promise when it is created
- In RedisClient -> Init -> channel.closureFuture.always
- Iterate through the stored promises and send a "ChannelError"
- Empty the storage object
Diff below
bash-3.2$ git diff
diff --git a/Sources/Redis/Client/RedisClient.swift b/Sources/Redis/Client/RedisClient.swift
index 177277a..901ec86 100644
--- a/Sources/Redis/Client/RedisClient.swift
+++ b/Sources/Redis/Client/RedisClient.swift
@@ -20,7 +20,10 @@ public final class RedisClient: DatabaseConnection, BasicWorker {
/// The channel
private let channel: Channel
-
+
+ /// Stores the inflight promises so they can be fulfilled when the channel drops
+ var inflightPromises: [String:EventLoopPromise<RedisData>] = [:]
+
/// Creates a new Redis client on the provided data source and sink.
init(queue: RedisCommandHandler, channel: Channel) {
self.queue = queue
@@ -28,6 +31,12 @@ public final class RedisClient: DatabaseConnection, BasicWorker {
self.extend = [:]
self.isClosed = false
channel.closeFuture.always {
+ // send closed error for the promises that have not been fulfilled
+ for promise in self.inflightPromises.values {
+ promise.fail(error: ChannelError.ioOnClosedChannel)
+ }
+ self.inflightPromises.removeAll()
+
self.isClosed = true
}
}
@@ -55,6 +64,13 @@ public final class RedisClient: DatabaseConnection, BasicWorker {
// create a new promise to fulfill later
let promise = eventLoop.newPromise(RedisData.self)
+ // logic to store in-flight requests
+ let key = UUID().uuidString
+ self.inflightPromises[key] = promise
+ promise.futureResult.always {
+ self.inflightPromises.removeValue(forKey: key)
+ }
+
// write the message and the promise to the channel, which the `RequestResponseHandler` will capture
return self.channel.writeAndFlush((message, promise))
.flatMap { return promise.futureResult }
@Mordil If this solution is acceptable, I'll create a PR accordingly. Let me know what you think
from redis.
@Mordil I created a PR for this. Use it if you desire. I needed to fix it for my needs regardless.
from redis.
@ericchapman Sorry for the extremely long delay in response - August has been way too busy for me.
I left a comment on the PR of where the code can live. The primary thing is the handler is missing a good implementation for either channelInactive
or something else to respond to the channel now closing - which is honestly a problem upstream w/ SwiftNIO Extras as well
from redis.
@Mordil That was what I was looking for! I knew the in-flight promises were stored somewhere already. I just needed to go a level deeper in the code. Let me know if my modified code is correct. And no problem being busy. It happens to all of us.
from redis.
Related Issues (20)
- Allow keyed cache access without `data` wrapper via `KeyedCacheSupporting` HOT 2
- Why does RedisClient use 'currentSend' to form an adhoc mutex? HOT 12
- Redis 4 Docs HOT 1
- redis.command not working properly - works only with INFO HOT 1
- Redis should provide a Application.Sessions.Provider HOT 1
- ERR max number of clients reached on Heroku free tier HOT 2
- Precondition failed in Redis 4.1.0 when using repository pattern HOT 14
- Random Server Crashes, 4.1.0 HOT 3
- Cannot connect to remote Redis. HOT 1
- PubSub not work with redis 4.1.0 HOT 3
- Change RediStack dependency to GitHub's HOT 3
- Add Key Expiration to Encodable Set HOT 1
- Sending the Redis transaction commands HOT 1
- Redis Lists commands HOT 1
- Connection pooling interfering with PubSub HOT 6
- Compiler warning: deprecated version of flatMapThrowing HOT 1
- SSL Connections (rediss) HOT 1
- Impossible to configure redis, if redis host name is unknown on time of launch
- Change the name of repository to follow new Redis licensing. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from redis.