Skip to content

Commit

Permalink
Prep for 0.2 release
Browse files Browse the repository at this point in the history
  • Loading branch information
Chakrit Wichian committed Jan 31, 2011
1 parent ae6aac5 commit da0d070
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 49 deletions.
108 changes: 66 additions & 42 deletions README.markdown
Expand Up @@ -4,26 +4,25 @@ SIDER : REDIS bindings for C#
Inspired by migueldeicaza's first stab at the problem (I used some of his Inspired by migueldeicaza's first stab at the problem (I used some of his
algorithm) and ServiceStack.Redis (to take it a lot further). algorithm) and ServiceStack.Redis (to take it a lot further).


This is a REDIS bindings for C# 4.0 that try to **stick to the metal** as much as This is a REDIS 2.2 bindings for C# 4.0 that try to **stick to the metal**
possible which results in: as much as possible which results in:


* Simple API that maps directly to the Redis commands reference. * Simple API that maps closely to the Redis commands reference.
* Easy to use, no gigantic class hierarchies to setup. No confusing method names. * Easy to use, no gigantic class hierarchies to setup. No confusing naming
convention that obfuscates the real command being sent to Redis.
* As fast as my limited networking skills will allow. * As fast as my limited networking skills will allow.
* Supports reading from and writing data to user-supplied streams for GET/SET * Supports reading from and writing data to user-supplied streams for GET/SET
and a few other similar commands to allow Redis to be used to store really and other similar commands to allow Redis to be used to store really
really large blobs (e.g. user-uploaded files) efficiently memory-wise. really large blobs (e.g. user-uploaded files) without huge buffers.
* Upcoming no-frill pipelining support. * Delegate-based pipelining support.


As of 24th July 2010, all basic commands have been implemented except for the As of 24th July 2010, all basic commands have been implemented except for the
following: following:


* Blocking commands `BLPOP`, `BLPUSH` and the likes. - Needs a few more tests * Extra options for some commands - e.g. `WITHSCORES`, `AGGREGATE` and the likes.
with varying Socket configurations. * Better transaction support - Right now you can use `MULTI`, `EXEC` and
* Extra options for some commands - e.g. `WITHSCORES` and `AGGREGATE` `DISCARD` inside the `.Pipeline` method which should be enough for most
* Transaction and pipelining support. - Sider has been designed from the ground cases.
up to make it easy to pipeline and do transactions, the foundation work is
already there. I just need a bit more time to finalize and streamline the API.


Other than that, it's solid and somewhat fault-tolerant. I'm using this myself Other than that, it's solid and somewhat fault-tolerant. I'm using this myself
in production code as well, so expect fast fixes should there be any problems. in production code as well, so expect fast fixes should there be any problems.
Expand All @@ -32,13 +31,13 @@ in production code as well, so expect fast fixes should there be any problems.


Here's how to use the lib: Here's how to use the lib:


// connects to redis
var client = new RedisClient(); // default host:port var client = new RedisClient(); // default host:port
client = new RedisClient("localhost", 6379); // custom client = new RedisClient("localhost", 6379); // custom host/port


// redis commands are methods of the RedisClient class // redis commands are methods of the RedisClient class
client.Set("HELLO", "World"); client.Set("HELLO", "World");
var result = client.Get("HELLO"); var result = client.Get("HELLO");

// result == "World"; // result == "World";


client.Dispose() // disconnect client.Dispose() // disconnect
Expand All @@ -52,35 +51,40 @@ the `ThreadwisePool` like this:
var client = pool.GetClient(); var client = pool.GetClient();
var result = client.Get("HELLO") == "WORLD"; var result = client.Get("HELLO") == "WORLD";


Internally, a .NET 40 `ThreadLocal<T>` is used. Internally, a .NET 40 `ThreadLocal<T>` is used. Both the client and the clients pool can be plugged into an IoC by using the respective

Both the client and the clients pool can be plugged into an IoC by using the respective
`IRedisClient` and `IClientsPool` interface respectively. `IRedisClient` and `IClientsPool` interface respectively.


You can also fine-tune buffer sizes to your liking by passing a # PIPELINE
`RedisSettings` instance like so:


var settings = new RedisSettings( To perform multiple pipelined calls, wrap your commands in a `.Pipeline` call:
host: "192.168.192.111",
port: 6379,
autoReconnectOnIdle: false, // if no idle client disconnection
readBufferSize: 256, // optimize for small reads
writeBufferSize: 65536); // optimize for heavy writes


var pool = new ThreadwisePool(settings); // issue ~ 2k commands in one go
var client = pool.GetClient(); var result = client.Pipeline(c =>
{
for (var i = 0; i < 1000; i++)
c.Set("HELLO" + i.ToString(), "WORLD" + i.ToString());


// or, pass directly to client for (var i = 999; i >= 0; i--)
client = new RedisClient(settings); c.Get("HELLO" + i.ToString()
});


... // parse results
var resultArr = result.ToArray();
for (var i = 0; i < 1000; i++) // SET results
Debug.Assert((bool)resultArr[i]);


# Pipeline for (var i = 999; i >= 0; i--) { // GET results
Debug.Assert(resultArr[i] is string);
Debug.Assert("WORLD" + i.ToString() == (string)resultArr[i]);
}


Experimental pipelining support is in, simply call the `Pipeline` method to Results are returned as an `IEnumerable<object>` with as many elements as
perform a pipelined call, with each result of the call returned inside a the number of calls you've made with each object having the same type as the
Tuple<> with same size as the number of calls or an IEnumerable<object> for a corresponding pipelined call.
long pipelined sessions
If you only need a fixed number of calls which you can determine at compile-time
then you can use the extension method version of `.Pipeline` to help you with
type-casting.


Example, for a fixed number of calls: Example, for a fixed number of calls:


Expand All @@ -94,10 +98,10 @@ Example, for a fixed number of calls:
string getResult = result.Item1; string getResult = result.Item1;
string[] mGetResults = result.Item2; string[] mGetResults = result.Item2;
string[] keysResults = result.Item3; string[] keysResults = result.Item3;

The returned value of these extension methods is a strongly-typed `Tuple<>`.


Example when doing more than 7 calls (the maximum size of a Tuple<>) or when Example when doing more than 7 calls:
you don't know the number of calls you'll be doing in advance (although, that
situation should be very unlikely):


// unlimited number of calls (don't abuse it though) // unlimited number of calls (don't abuse it though)
var result = client.Pipeline(c => { var result = client.Pipeline(c => {
Expand All @@ -116,11 +120,31 @@ situation should be very unlikely):
Trace.Assert(resultArr[2] == /* value from KEY3 */); Trace.Assert(resultArr[2] == /* value from KEY3 */);
// ... // ...


MULTI EXEC is coming right up with a similar syntax... hopefully before January ends :) Note that pipeline results are not lazy as is the case with many `IEnumerable`

implementation -- All commands will be executed immediately as soon as you
finish the `.Pipeline` call.

# CONFIGS

You can fine-tune buffer sizes to your liking by passing a
`RedisSettings` instance like so:

var settings = new RedisSettings(
host: "192.168.192.111",
port: 6379,
autoReconnectOnIdle: false, // if no idle client disconnection
readBufferSize: 256, // optimize for small reads
writeBufferSize: 65536); // optimize for heavy writes

var pool = new ThreadwisePool(settings);
var client = pool.GetClient();

// or, pass directly to client
client = new RedisClient(settings);

... ...


# License # LICENSE


Copyright (c) 2010, Chakrit Wichian. Copyright (c) 2010, Chakrit Wichian.
All rights reserved. All rights reserved.
Expand Down
18 changes: 13 additions & 5 deletions Sider.nuspec
Expand Up @@ -2,18 +2,26 @@
<package> <package>
<metadata> <metadata>
<id>Sider</id> <id>Sider</id>
<version>0.1</version> <version>0.2</version>
<description> <description>
Sider on GitHub: http://github.com/chakrit/sider -- SIDER : REDIS bindings for C#/.NET 4.0 --
SIDER : REDIS bindingts for C#/.NET 4.0 ... GitHub: http://github.com/chakrit/sider
minimal, lightweight, easy to use, no fancy APIs. assumes knowledge of how Redis works. nuget.org: http://nuget.org/

Redis client that sticks to the metal.
Minimal, lightweight, easy to use, no fancy APIs, no gigantic class hierarchies.
Assumes knowledge of how Redis works.

Suggestions/fixes welcome, just mention @chakrit on twitter.

Sider 0.2 works with Redis 2.2.
</description> </description>
<language>en-us</language> <language>en-us</language>
<authors> <authors>
<author>Chakrit Wichian (http://chakrit.net/)</author> <author>Chakrit Wichian (http://chakrit.net/)</author>
</authors> </authors>
</metadata> </metadata>
<!-- Package file for use with http://nupackpackages.codeplex.com/ --> <!-- Package file for use with http://nuget.org/ -->
<!-- To use it locally, uncomment these lines: --> <!-- To use it locally, uncomment these lines: -->
<!-- <files src="build\Sider.dll" target="lib" /> --> <!-- <files src="build\Sider.dll" target="lib" /> -->
<!-- <files src="build\Sider.pdb" target="lib" /> --> <!-- <files src="build\Sider.pdb" target="lib" /> -->
Expand Down
4 changes: 2 additions & 2 deletions SiderAssemblyInfo.cs
Expand Up @@ -14,5 +14,5 @@
[assembly: InternalsVisibleTo("Sider.Tests")] [assembly: InternalsVisibleTo("Sider.Tests")]


#pragma warning disable 1607 #pragma warning disable 1607
[assembly: AssemblyVersion("0.1.*")] [assembly: AssemblyVersion("0.2.*")]
[assembly: AssemblyFileVersion("0.1.*")] [assembly: AssemblyFileVersion("0.2.*")]
Binary file modified sider.logo.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit da0d070

Please sign in to comment.