vapor / redis Goto Github PK
View Code? Open in Web Editor NEWVapor provider for RediStack
License: MIT License
Vapor provider for RediStack
License: MIT License
http://www.rediscookbook.org/multiple_databases.html
Could be something in the config
The API to configure Redis is currently not public. This is well within my new guy abilities. So I am going to take a stab at it.
I'm trying to set an hmap with this line :
let message = try client!.command("HMSET", params: ["messages", "content", "blalba", "token", "123456"])
let writtenMessages = try client.command("HGET", params: ["messages", "content"])
But printing writtenMessages.toString() gives me the "OK" message instead of the content...
I have no idea how to do this, so is this supported, if so how do you do it ?
I just tried to use a redis password and I suspect the auth command never gets executed
https://github.com/vapor/redis/blob/master/Sources/Redis/Database/RedisDatabase.swift#L27
The auth command future is created, but (if I understand event loops correctly) never executed
Adding .package(url: "https://github.com/vapor/sockets.git", .branch("beta")),
to its Package.swift
seems to solve it.
redis/Sources/Redis/Coders/RedisDataDecoder.swift
Lines 60 to 63 in c47af5b
buffer =
"*50\r\n$5\r\ntest0\r\n$5\r\ntest1\r\n$6\r\ntest10\r\n$6\r\ntest11\r\n$6\r\ntest12\r\n$6\r\ntest13\r\n$6\r\ntest14\r\n$6\r\ntest15\r\n$6\r\ntest16\r\n$6\r\ntest17\r\n$6\r\ntest18\r\n$6\r\ntest19\r\n$5\r\ntest2\r\n$6\r\ntest20\r\n$6\r\ntest21\r\n$6\r\ntest22\r\n$6\r\ntest23\r\n$6\r\ntest24\r\n$6\r\ntest25\r\n$6\r\ntest26\r\n$6\r\ntest27\r\n$6\r\ntest28\r\n$6\r\ntest29\r\n$5\r\ntest3\r\n$6\r\ntest30\r\n$6\r\ntest31\r\n"
position = 314
token = 54
Currently the toInt()
method only succeeds when Redis returns an explicit integer
type, prefixed with :
. This may be expected behavior, but I don't find it particularly useful since most types are returned as bulk string
.
Would you consider expanding the toInt()
method to convert bulk string
s to Int
as well?
Hello,
More a question than an issue: i'm playing with your redis client and I'm wrapping it in a class to abstract db specific stuff in my app. I have a problem initializing this class though since init of Redis throws.
Here's what I'm trying to do:
class RedisManager {
let client: Redbird
init(address: String, port: UInt16, password: String? = nil) {
do {
let config = RedbirdConfig(address: address, port: port, password: password)
client = try Redbird(config: config)
} catch {
Log.error("Could not connect to Redis instance")
}
}
...
# Api like setArray, getString ...
}
This fails with error:
Return from initializer without initializing all stored properties
I want to keep an instance of Redis as a stored property because it seems wasteful to recreate it inside a do catch every time I want to access db.
Any idea how to instantiate Redis in init of my class and assign it to self.client?
There is an issue when subscribing to multiple Channels with Redis. PubSub with a single channel works just fine but as soon as multiple channels are attempted there is an issue. I used redis-cli
and MONITOR
to investigate this "SUBSCRIBE" command goes across the wire as expected however no channel data is coming out of the drain. RedisDataParser does not get channel data that it can decipher.
I can provide sample code to reproduce this if that is what is desired.
Facilities to handle Null Array (namely, *-1\r\n
) isn't present.
Relevant code can be found here at RedisDataParser.swift:195
The protocol specification, search for null array
.
Should be able to connect like this:
connection::create_unix("/tmp/redis.sock");
// C++ code
The API to subscribe to Redis is currently not public. This is well within my new guy abilities. So I am going to take a stab at it.
Apologies if I missed something, but it seems like pub-sub is currently not supported? From what I see, when calling command
, it does both a write and a read of the response on the socket, and there's no finer-grained method to just emit a write and a separate one for the reads, which are required for pub-sub (you call [P]SUBSCRIBE
with a write, and then wait for messages by reading on the socket - it typically can't be used for other writes except to subscribe/unsubscribe to/from other channels).
For example, the redigo package in Go has separate Send/Flush calls to write, and Receive to read, and a convenience Do method that combines them for the common commands that immediately return a value (https://godoc.org/github.com/garyburd/redigo/redis#Conn). It also provides a PubSubConn type as convenience, built from the Send/Flush/Receive primitives (https://godoc.org/github.com/garyburd/redigo/redis#PubSubConn).
#70 related
Allow connections to be pooled and re-used.
The current README.md includes the reference to an older repository instead of this one.
Hello, so I've been planning on updating an application of mine that used the version 1 of this library to the more recent one, and I'm having some doubts about how to proceed.
It seems that not all of the available redis operations are defined now, for example, how do I convert 'MULTI', 'EXEC', 'HGETALL', etc?
Also, is there any documentation (or blog post, etc) with some examples on the recent version?
Cheers!
Is there a way to authenticate using user/password ? (For Heroku's Redis service)
Hi,
What about swift 4 support?
Running wrk -t4 -c100 -d10s http://127.0.0.1:8080/test creates 358 megabytes of memory for me.
Currently happening on 3.0.0-rc.
struct Car: Content {
let wheels: Int
let color: String
let horsepower: Int
let brand: String
}
func test(_ req: Request) throws -> Future<Car> {
let client = try req.make(RedisClient.self)
return try client.get(Car.self, forKey: "car").unwrap(or: "ERROR")
}
After playing around with this for a while. I figured out the reason for the error was in here.
If you store a key:value and retrieve it fast enough, in some cases you will only get some of the value string back
ex
sometimes: GET:{"dat
should be: GET:{"data":null}
I managed to replicate this, by setting up a sessionmiddleware with redis cache. And then refresh a view which is using files from public folder
maybe it's related to: #31?
Is there any option to select database while connecting redis?
I kind of goofed up and did not spec that Redis client should throw on connection failure... I will fix it.
Using the run(command:arguments:)
should succeed!
Using the run(command:arguments:)
, I encountered many such errors. I cannot pin point the exact condition for this to happen since it sometimes work.
Fatal error: input was called while inputBuffer is not nil: file /Users/hsupengjun/Projects/Libraries/JARPC-upstream/.build/checkouts/async.git-2335297525913451934/Sources/Async/Socket/SocketSink.swift, line 44
Illegal instruction: 4
The code that could cause the error (there are quite some more),
_ = client.run(command: "LPUSH", arguments: [.bulkString(target), .bulkString(data)])
_ = client.run(command: "LREM", arguments: [.bulkString(processingQueue), "0", .bulkString(work)])
The resolved packages,
{
"package": "Async",
"repositoryURL": "https://github.com/vapor/async.git",
"state": {
"branch": "beta",
"revision": "e2dec3c2013d5c71e3ebace661344de7d1259b79",
"version": null
}
},
{
"package": "Redis",
"repositoryURL": "https://github.com/vapor/redis.git",
"state": {
"branch": "beta",
"revision": "2d150f6ec90b1071a0633272180c4dafc1043f92",
"version": null
}
},
Screenshot of call stack,
I actually don't know how.
If my bug report is malformed or otherwise, please mention me. I can provide exact code through PM in Slack if needed. :)
Many redis commands are composed of multiple words, but in Redbird.swift
there's a validation that the command must be a single word otherwise it's an error (RedbirdError.moreThanOneWordSpecifiedAsCommand
).
e.g. if you try client.command("CONFIG GET", params: ["*"])
.
IMO you shouldn't try to validate the command at all, as redis will soon support modules which may define additional commands (currently in the unstable branch), and the config allows to rename known commands to something else (see rename-command
in https://raw.githubusercontent.com/antirez/redis/3.0/redis.conf). I think you should consider whatever's passed into command
method to be the command to execute.
redis/Sources/Redis/Coders/RedisDataDecoder.swift
Lines 166 to 169 in b451896
Stumbled upon the crash today with slicing bytes
array with size
out of range.
The state at that moment was:
size == 10
buffer.readableBytes == 115
position == 113
bytes: 2 elements
and the buffer.readString(length: 115)
output
"*8\r\n$16\r\ntest8:1523640910\r\n$10\r\n1523640910\r\n$16\r\ntest9:1523640913\r\n$10\r\n1523640913\r\n$17\r\ntest10:1523640916\r\n$10\r\n15"
Is out of range expected behaviour with that buffer?
Redbird is not thread-safe, which causes problems when using it with Swift web frameworks. A single Redbird
instance cannot be shared across the application, since multiple threads may require simultaneous access. Establishing a new connection for every request would be wasteful and silly.
This leaves us with two options:
Redbird
instance. For example:dispatch_sync(com.myApp.redbirdSerialQueue) {
redbird.command(...)
}
command()
may be synchronized as such:public func command(_ name: String, params: [String] = []) throws -> RespObject {
dispatch_sync(com.redbird.serialQueue) {
...
}
}
Correct me if I'm wrong (because I'm not familiar with the entire codebase), but concurrent access to a shared Redbird
instance should be safe since none of its properties are mutated after initialization.
I personally believe that option 2 is much safer and easier. What do you think? I can make the changes if you agree that thread safety should be addressed.
do{
let result = try redis.command("SETNX", params: ["test", "redbird"]).toString()
}
catch{
print(error) //This prints wrongNativeTypeUnboxing(Redbird.RespInteger(respType: Redbird.RespType.Integer, intContent: 0), "String")
}
I checked the key in my redis and the value is successfully set
127.0.0.1:6379> get test
"redbird"
There is some problem with setnx command. Please resolve this issue as it is throwing error even if there is success
update redis' parser/serializer for max performance :)
Stream buffer shouldn't call the underlying stream send directly. Only on flush.
I added a PR for this here #74
It would be nice to have a way to send multiple commands at once. This api feels a bit out of place now in vapor 3 but something similar would be nice.
let pipeline = connection.makePipeline()
let result = try pipeline
.enqueue(command: "SET", arguments: ["KEY", "VALUE"])
.enqueue(command: "INCR", arguments: ["COUNT"])
.execute() // Future<[RedisData]>
Hi czechboy0,
is it possible to support cocoapods as package manager too?
That would be great.
Seppelandrio
can u deploy by Carthage or pod?
可以使用Carthage 或者 pod来发布吗?
Look into automatically generating that code based on official docs https://github.com/antirez/redis-doc
Currently there is no way to setup Redis with a Keyed Session because that requires access to the RedisClient
, which we don't have during the setup.
From the Slack:
Ideally the keyed cache would take either a Future to redis, or a connection pool
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.