aerospike / aerospike-client-csharp

Aerospike C# Client Library
70 stars 47 forks source link

Async extensions for AsyncClient #4

Closed olviko closed 9 years ago

olviko commented 9 years ago

It is quite hard to use AsyncClient, especially when I have to integrate it with client code based on the Task-based Asynchronous Pattern (TAP). Added xxxAsync overloads to most of the calls, except ones that use sequence listeners.

Example

        public async Task<string> Example(AsyncClient asyncClient, CancellationToken token)
        {
            string ns = "test";
            string set = "asyncTest";
            Key key = new Key(ns, set, 123);

            await asyncClient.PutAsync(token, null, key, new Bin("x", "xvalue"));
            Record r = await asyncClient.GetAsync(token, null, key);

            return (string)r.GetValue("x");
        }
BrianNichols commented 9 years ago

We are performing a C# client release this week. We will look into these modifications possibly for the release after that.

manigandham commented 9 years ago

@olviko This is great, been meaning to work on this myself.

olviko commented 9 years ago

@BrianNichols Great timing! Now that Lua has been replaced, did you get any chance to test the new version on Linux/Mono?

olviko commented 9 years ago

@BrianNichols The code below won't run on Mono. Is it really necessary to use P/Invoke here?

Utils.cs

        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int memcmp(byte[] b1, byte[] b2, long count);

        public static bool ByteArrayEquals(byte[] b1, byte[] b2)
        {
            return b1.Length == b2.Length && memcmp(b1, b2, b1.Length) == 0;
        }

could be replaced with

public static bool ByteArrayEquals(byte[] a1, byte[] a2)
{
  if (a1 == a2)
  {
    return true;
  }
  if (a1 != null && a2 != null)
  {
    if (a1.Length != a2.Length)
    {
      return false;
    }
    for (int i = 0; i < a1.Length; i++)
    {
      if (a1[i] != a2[i])
      {
        return false;
      }
    }
    return true;
  }
  return false;
}
BrianNichols commented 9 years ago

We haven't tested on mono. The low level memcmp was used for performance. It can re-implemented for Mono using an if directive (#if). Let us know if there are any more issues and we will fix them in one pass.

olviko commented 9 years ago

The conditional compilation statement would work, but would also complicate cross-platform deployment. We'd have to copy different dll for each platform instead of relying on project references. A quick benchmark of the client library didn't show noticeable differences between the original memcmp code and the managed version I posted.

BrianNichols commented 9 years ago

The memcmp code is only called for batch.

You can avoid conditional compilation by adding the following to your "app.config" file when running mono.

<configuration> <dllmap dll="msvcrt.dll" target="libc.so.6" /> </configuration>

Details here: http://stackoverflow.com/questions/13923857/is-there-a-memcmp-equivalent-for-comparing-byte-arrays-in-mono

BrianNichols commented 9 years ago

The Task based extensions have been integrated and merged into the AsyncClient class itself. These changes will appear in the next C# client release.