Just a quick note to say that I have made some minor changes to DynamoDb.SQL and released ver­sion 1.0.7 of the library to Nuget, here’s a list of the changes:

  • fixed a bug with LIMIT when there is insuf­fi­cient num­ber of ele­ments using the DynamoD­B­Con­text.
  • added sup­port for count­ing the num­ber of match­ing items with a query or scan (see below)

image

image

The Get­ting Started guide has also been updated to include details on how to write a Count query.

Share

NOTE: if you’re unfa­mil­iar with how Post­Sharp works under the hood, I highly rec­om­mend that you check out Dustin Davis’ excel­lent Post­Sharp Prin­ci­ples series of blog posts here.

The Prob­lem

The new async/await key­words in C# are pretty awe­some, and makes life an awful lot eas­ier when writ­ing asyn­chro­nous and non-blocking IO code. How­ever, for those of us who are using frame­works such as Post­Sharp to deal with cross-cutting con­cerns we now face a new chal­lenge – the aspects which we have come to rely upon no longer works the way we expect them to when applied on async meth­ods (which returns void, Task or Task<T>), as can be seen from the exam­ples below:

So what’s wrong here?

If you take a look at the code from the above exam­ple using a decom­piler such as Jet­Brain’s Dot­Peek, you’ll see that the nor­mal syn­chro­nous ver­sion of Foo looks some­thing along the line of:

image

As you can see, the weaved code include calls to the OnEn­try, OnSuc­cess and OnEx­cep­tion meth­ods pro­vided by the OnMethod­Bound­aryAspect class, so every­thing is as expected here.

For FooA­sync how­ever, the pic­ture is a lit­tle more complicated:

image

Turns out the C# com­piler rewrites async meth­ods into a state machine which means that although the OnSuc­cess and OnEx­cep­tion hooks are still in place, they’re not telling us when the body of the method suc­ceeds or fails but instead, when the state machine cre­ation has suc­ceeded or failed!

image

image

Pretty big bum­mer, eh?

Pro­posed Solution

One way (and the best way I can think of for now) to get around this is to have a spe­cial aspect which works with meth­ods that return Task or Task<T> and hook up con­tin­u­a­tions to be exe­cuted after the returned tasks had fin­ished. Some­thing sim­i­lar to the below will do for the on method bound­ary aspect:

And then you can cre­ate a TraceA­sync attribute that works for async methods:

As you can see from the out­put above, our new OnTask­Fin­ished, OnTask­Faulted and OnTaskCom­ple­tion hooks are cor­rectly exe­cuted after the task returned by the async method had fin­ished, faulted due to excep­tion or ran to completion!

The same approach can also be applied to other built-in aspects such as the Method­In­ter­cep­tionAspect class.

Before you go…

How­ever, there are a two things you should con­sider first before jump­ing into the workaround pro­posed above.

1. if you look at the out­put from the pre­vi­ous exam­ple care­fully, you’ll see that the line “FooA­sync fin­ished” came AFTEREnter­ing Boo” even though from the test code we have awaited the com­ple­tion of FooA­sync before call­ing Boo. This is because the con­tin­u­a­tions are exe­cuted asynchronously.

If this behav­iour is not desir­able to you, there is a very sim­ple fix. Back in the OnA­syncMethod­Bound­Aspect class we defined above, sim­ply add TaskContinuationOptions.ExecuteSynchronously to each of the continuations:

image

2. the pro­posed solu­tion still wouldn’t work with async meth­ods that return void sim­ply because there are no returned Task/Task<T> objects to hook up con­tin­u­a­tions with. In gen­eral though, you should avoid hav­ing async void meth­ods as much as pos­si­ble because they intro­duce some pit­falls which you really wouldn’t want to find your­self in! I’ve dis­cussed the prob­lem with aysnc void (and some poten­tial workarounds) in a pre­vi­ous post here.

 

I hope this post proves use­ful to you, and happy PostSharp’ng! I hear some big things are com­ing in this space Winking smile

Share

Just a quick note to say that I have made some minor changes to DynamoDb.SQL to:

  • Add sup­port for spec­i­fy­ing the ScanIn­dex­For­ward option(see DynamoDB API doc here for detail) in a Query oper­a­tion using an optional “ORDER” clause

image

  • Fixed a bug where when query­ing using the exten­sion meth­ods on the DynamoD­B­Con­text class, the LIMIT clause is not being respected. This was due to lazy-loading of results in the DynamoD­B­Con­text class, see this thread for more info.

 

The lat­est build can be found on Nuget as ver­sion 1.0.5.

Share

Just a quick note to say that I have updated the JSON seri­al­iz­ers bench­mark to use the lat­est Nuget ver­sions of ServiceStack.Text, Json.Net and JsonFX.

I have also included the JSON and BSON seri­al­iz­ers from the Mon­goDB C# Dri­ver in the test, and since BSON is a binary for­mat I have included protobuf-net as a ref­er­ence since it’s the fastest binary seri­al­izer I know of on the .Net platform:

image

image

Com­pared to the last set of results, you can see that the lat­est ver­sion of JsonFX seems have gone much much slower on dese­ri­al­iza­tion, whilst ServiceStack.Text is still the fastest JSON seri­al­izer around. The Mon­goDB C# Dri­ver’s JSON and BSON both held up pretty well in the test too.

Share

Amazon’s DynamoDB is a won­der­ful prod­uct – scal­able, durable, fast, with pre­dictable latency num­bers unlike Sim­pleDB. How­ever, the only gripe I have with DynamoDB is that there is no built-in sup­port for a query lan­guage, which makes life rather dif­fi­cult when you want to per­form a query or a scan against the data you have in DynamoDB.

Whilst the stan­dard AWS SDK for .Net pro­vides a num­ber of dif­fer­ent ways to per­form queries and scans:

  • using the low-level Ama­zon­Dy­namoD­B­Client
  • using the Table helper class
  • using the DynamoD­B­Con­text ORM

none of these ways are easy to use and the few attempts to use them in our code­base left a bad taste in my mouth and an exter­nal DSL is des­per­ately needed to make it eas­ier to express the query we’d like to per­form against data stored in DynamoDB.

Intro­duc­ing DynamoDb.SQL

It is because of these lim­i­ta­tions that I decided to add a SQL-like exter­nal DSL on top of exist­ing func­tion­al­i­ties to make it eas­ier for .Net devel­op­ers to work with DynamoDB.

Hav­ing spent a cou­ple of week­ends I have put together a sim­ple library called DynamoDb.SQL, which you can down­load and try it your­self from Nuget here. This library adds an exter­nal DSL on top of the exist­ing func­tion­al­i­ties of the .Net AWS SDK and allows you to query and scan DynamoDB using nat­ural, SQL-like syntax.

Using this syn­tax, a query can be expressed with the gen­eral format:

image

where @HashKey and @RangeKey are spe­cial key­words to mean the hash and range key in your table, and oper­a­tor can be one of the allowed com­par­i­son oper­a­tors for a query request :

=, >=, >, <=, <, BEGINS WITH and BETWEEN .. AND ..

Sim­i­larly, a scan can be expressed with the gen­eral format:

image

where operator1 to oper­a­torN can be one of the allowed com­par­i­son oper­a­tors in a scan request :

=, !=, >=, >, <=, <, CONTAINS, NOT CONTAINS, BEGINS WITH, IS NULL, IS NOT NULL, BETWEEN .. AND .., and IN (…)

To learn more about the syn­tax and how to use DynamoDb.SQL, take a look at the Get­ting Started guide here.

 

Links:

DynamoDB APIQuery­ing and Scan­ning

DynamoDB – Query­ing and Scan­ning using low-level Ama­zon­Dy­namoD­B­Client

DynamoDB – Query­ing and Scan­ning using Table helper class

DynamoDB – Query­ing and Scan­ning using high-level DynamoD­B­Con­text

Share