Looking at Guava Cache we think its API is more convenient than .NET's Cache API.
Just consider:
-
.NET has getters, and setters of object s by string keys.
You should provide caching policy with each setter.
-
Guava cache operates with typed storage of Key to Value.
Provides a value factory and a caching policy in advance at cache construction.
Guava's advantange is based on an idea that homogenous storage assumes a uniform way of creation of values, and uniform caching policy. Thus a great part of logic is factored out into a cache initialization.
We have decided to create a simple adapter of the MemoryCache to achieve the same goal. Here is a result of such an experiment:
public class Cache<K, V>
where V: class
{
/// <summary>
/// A cache builder.
/// </summary>
public struct Builder
{
/// <summary>
/// A memory cache. If not specified then MemoryCache.Default is used.
/// </summary>
public MemoryCache MemoryCache;
/// <summary>
/// An expiration value.
/// Alternatively CachePolicyFunc can be used.
/// </summary>
public TimeSpan Expiration;
/// <summary>
/// Indicates whether to use sliding (true), or absolute (false)
/// expiration.
/// Alternatively CachePolicyFunc can be used.
/// </summary>
public bool Sliding;
/// <summary>
/// Optional function to get caching policy.
/// Alternatively Expiration and Sliding property can be used.
/// </summary>
public Func<V, CacheItemPolicy> CachePolicyFunc;
/// <summary>
/// Optional value validator.
/// </summary>
public Func<V, bool> Validator;
/// <summary>
/// A value factory.
/// Alternatively FactoryAsync can be used.
/// </summary>
public Func<K, V> Factory;
/// <summary>
/// Async value factory.
/// Alternatively Factory can be used.
/// </summary>
public Func<K, Task<V>> FactoryAsync;
/// <summary>
/// A key to string converter.
/// </summary>
public Func<K, string> KeyFunc;
/// <summary>
/// Converts builder to a Cache<K, V> instance.
/// </summary>
/// <param name="builder">A builder to convert.</param>
/// <returns>A Cache<K, V> instance.</returns>
public static implicit operator Cache<K, V>(Builder builder)
{
return new Cache<K, V>(builder);
}
}
/// <summary>
/// Creates a cache from a cache builder.
/// </summary>
/// <param name="builder">A cache builder instance.</param>
public Cache(Builder builder)
{
if ((builder.Factory == null) && (builder.FactoryAsync == null))
{
throw new ArgumentException("builder.Factory");
}
if (builder.MemoryCache == null)
{
builder.MemoryCache = MemoryCache.Default;
}
this.builder = builder;
}
/// <summary>
/// Cached value by key.
/// </summary>
/// <param name="key">A key.</param>
/// <returns>A cached value.</returns>
public V this[K key]
{
get { return Get(key); }
set { Set(key, value); }
}
/// <summary>
/// Sets a value for a key.
/// </summary>
/// <param name="key">A key to set.</param>
/// <param name="value">A value to set.</param>
public void Set(K key, V value)
{
SetImpl(GetKey(key), IsValid(value) ? value : null);
}
/// <summary>
/// Gets a value for a key.
/// </summary>
/// <param name="key">A key to get value for.</param>
/// <returns>A value instance.</returns>
public V Get(K key)
{
var keyValue = GetKey(key);
var value = builder.MemoryCache.Get(keyValue) as V;
if (!IsValid(value))
{
value = CreateValue(key);
SetImpl(keyValue, value);
}
return value;
}
/// <summary>
/// Gets a task to return an async value.
/// </summary>
/// <param name="key">A key.</param>
/// <returns>A cached value.</returns>
public async Task<V> GetAsync(K key)
{
var keyValue = GetKey(key);
var value = builder.MemoryCache.Get(keyValue) as V;
if (!IsValid(value))
{
value = await CreateValueAsync(key);
SetImpl(keyValue, value);
}
return value;
}
/// <summary>
/// Gets string key value for a key.
/// </summary>
/// <param name="key">A key.</param>
/// <returns>A string key value.</returns>
protected string GetKey(K key)
{
return builder.KeyFunc != null ? builder.KeyFunc(key) :
key == null ? null : key.ToString();
}
/// <summary>
/// Creates a value for a key.
/// </summary>
/// <param name="key">A key to create value for.</param>
/// <returns>A value instance.</returns>
protected V CreateValue(K key)
{
return builder.Factory != null ? builder.Factory(key) :
builder.FactoryAsync(key).Result;
}
/// <summary>
/// Creates a task for value for a key.
/// </summary>
/// <param name="key">A key to create value for.</param>
/// <returns>A task for a value instance.</returns>
protected Task<V> CreateValueAsync(K key)
{
return builder.FactoryAsync != null ? builder.FactoryAsync(key) :
Task.FromResult(builder.Factory(key));
}
/// <summary>
/// Validates the value.
/// </summary>
/// <param name="value">A value to validate.</param>
/// <returns>
/// true if value is valid for a cache, and false otherise.
/// </returns>
protected bool IsValid(V value)
{
return (value != null) &&
((builder.Validator == null) || builder.Validator(value));
}
/// <summary>
/// Set implementation.
/// </summary>
/// <param name="key">A key to set value for.</param>
/// <param name="value">A value to set.</param>
/// <returns>A set value.</returns>
private V SetImpl(string key, V value)
{
if (value == null)
{
builder.MemoryCache.Remove(key);
}
else
{
builder.MemoryCache.Set(
key,
value,
builder.CachePolicyFunc != null ? builder.CachePolicyFunc(value) :
builder.Sliding ?
new CacheItemPolicy { SlidingExpiration = builder.Expiration } :
new CacheItemPolicy
{
AbsoluteExpiration = DateTime.Now + builder.Expiration
});
}
return value;
}
/// <summary>
/// Cache builder.
/// </summary>
private Builder builder;
}
The use consists of initialization:
Cache<MyKey, MyValue> MyValues =
new Cache<MyKey, MyValue>.Builder
{
KeyFunc = key => ...key to string value...,
Factory = key => ...create a value for a key...,
Expiration = new TimeSpan(0, 3, 0),
Sliding = true
};
and a trivial cache access:
var value = MyValues[key];
This contrasts with MemoryCache coding pattern:
MemoryCache cache = MemoryCache.Default;
...
var keyAsString = ...key to string value...
var value = cache.Get(keyAsString) as MyValue;
if (value == null)
{
value = ...create a value for a key...
cache.Set(keyAsString, value, ...caching policy...);
}
These days we're not active xslt developers, though we still consider xslt and xquery are important part of our personal experience and self education.
Besides, we have a pretty large xslt code base that is and will be in use. We think xslt/xquery is in use in many other big and small projects thus they have a strong position as a niche languages.
Thus we think it's important to help to those who support xslt/xquery engines.
That's what we're regularly doing (thanks to our code base).
Now, to the problem we just have found. Please consider the code:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:t="this"
exclude-result-prefixes="xs t">
<xsl:template match="/">
<xsl:param name="new-line-text" as="xs:string" select="'
'"/>
<xsl:variable name="items" as="item()*" select="'select', $new-line-text"/>
<xsl:message select="t:string-join($items)"/>
</xsl:template>
<!--
Joins adjacent string items.
$items - items to join.
Returns joined items.
-->
<xsl:function name="t:string-join" as="item()*">
<xsl:param name="items" as="item()*"/>
<xsl:variable name="indices" as="xs:integer*" select="
0,
index-of
(
(
for $item in $items return
$item instance of xs:string
),
false()
),
count($items) + 1"/>
<xsl:sequence select="
for $i in 1 to count($indices) - 1 return
(
$items[$indices[$i]],
string-join
(
subsequence
(
$items,
$indices[$i] + 1,
$indices[$i + 1] - $indices[$i] - 1
),
''
)
)"/>
</xsl:function>
</xsl:stylesheet>
The output is:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: -1
at net.sf.saxon.om.Chain.itemAt(Chain.java:161)
at net.sf.saxon.om.SequenceTool.itemAt(SequenceTool.java:130)
at net.sf.saxon.expr.FilterExpression.iterate(FilterExpression.java:1143)
at net.sf.saxon.expr.LetExpression.iterate(LetExpression.java:365)
at net.sf.saxon.expr.instruct.BlockIterator.next(BlockIterator.java:49)
at net.sf.saxon.expr.MappingIterator.next(MappingIterator.java:70)
at net.sf.saxon.expr.instruct.Message.processLeavingTail(Message.java:264)
at net.sf.saxon.expr.instruct.Block.processLeavingTail(Block.java:660)
at net.sf.saxon.expr.instruct.Template.applyLeavingTail(Template.java:239)
at net.sf.saxon.trans.Mode.applyTemplates(Mode.java:1057)
at net.sf.saxon.Controller.transformDocument(Controller.java:2088)
at net.sf.saxon.Controller.transform(Controller.java:1911)
...
The problem is reported at: Exception during execution in Saxon-HE-9.5.1-6 and also tracked at https://saxonica.plan.io/issues/2104.
Update: according to Michael Kay the issue is fixed. See note #4:
I have committed a patch to Chain.itemAt() on the 9.5 and 9.6 branches to check for index<0
Enumerable class contains many overloads with IEqualityComparable<T> argument. Most notable methods are:
- Contains;
- Distinct;
- Except;
- GroupBy;
- Intersect;
- Join;
- ToDictionary;
- ToLookup;
- Union.
Recently we dealt with simple case:
source.
Select(
item =>
new Word
{
Text = ...,
LangID = ...,
Properties = ...
...
}).
Distinct(equality comparer by Text and LangID);
In other words how do you produce a enumeration of distinct words from a enumeration of words, where two words are qualified equal if their Text and LangID are equal?
It turns out it's cumbersome to implement IEqualityComparer<T> interface (and any other interface in C#), at least it's nothing close to a conciseness of lambda functions.
Here we've decided to step in into framework space and to introduce an API to define simple equality comparers for a class.
We start from the use case:
var wordComparer =
KeyEqualityComparer.Null<Word>().
ThenBy(item => item.Text).
ThenBy(item => item.LangID);
...
source.Select(...).Distinct(wordComparer);
And then proceed to the API:
namespace NesterovskyBros.Linq
{
using System;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// A equality comparer extensions.
/// </summary>
public static class KeyEqualityComparer
{
/// <summary>
/// Gets null as equality comparer for a type.
/// </summary>
/// <typeparam name="T">A type.</typeparam>
/// <returns>
/// null as equality comparer for a type.
/// </returns>
public static IEqualityComparer<T> Null<T>()
{
return null;
}
/// <summary>
/// Creates an equality comparer for a enumeration item.
/// </summary>
/// <typeparam name="T">A type.</typeparam>
/// <param name="source">A source items.</param>
/// <param name="keyFunc">A key function.</param>
/// <returns>
/// null as equality comparer for a type.
/// </returns>
public static IEqualityComparer<T> EqualityComparerBy<T, K>(
this IEnumerable<T> source,
Func<T, K> keyFunc)
{
return new KeyEqualityComparer<T, K>(keyFunc);
}
/// <summary>
/// Creates an equality comparer that uses this comparer as a base.
/// </summary>
/// <typeparam name="T">A type.</typeparam>
/// <typeparam name="K">A key type.</typeparam>
/// <param name="equalityComparer">A base equality comparer.</param>
/// <param name="keyFunc">A key function.</param>
/// <returns>
/// An equality comparer that uses this comparer as a base.
/// </returns>
public static KeyEqualityComparer<T, K> ThenBy<T, K>(
this IEqualityComparer<T> equalityComparer,
Func<T, K> keyFunc)
{
return new KeyEqualityComparer<T, K>(keyFunc, equalityComparer);
}
}
/// <summary>
/// Equality comparer that uses a function to extract a comparision key.
/// </summary>
/// <typeparam name="T">A type.</typeparam>
/// <typeparam name="K">A key type.</typeparam>
public struct KeyEqualityComparer<T, K>: IEqualityComparer<T>
{
/// <summary>
/// Creates an equality comparer.
/// </summary>
/// <param name="keyFunc">A key function.</param>
/// <param name="equalityComparer">A base equality comparer.</param>
public KeyEqualityComparer(
Func<T, K> keyFunc,
IEqualityComparer<T> equalityComparer = null)
{
KeyFunc = keyFunc;
EqualityComparer = equalityComparer;
}
/// </summary>
/// <param name="x">The first object of type T to compare.</param>
/// <param name="y">The second object of type T to compare.</param>
/// <returns>
/// true if the specified objects are equal; otherwise, false.
/// </returns>
public bool Equals(T x, T y)
{
return ((EqualityComparer == null) || EqualityComparer.Equals(x, y)) &&
EqualityComparer<K>.Default.Equals(KeyFunc(x), KeyFunc(y));
}
/// <summary>
/// Returns a hash code for the specified object.
/// </summary>
/// <param name="obj">
/// The value for which a hash code is to be returned.
/// </param>
/// <returns>A hash code for the specified object.</returns>
public int GetHashCode(T obj)
{
var hash = EqualityComparer<K>.Default.GetHashCode(KeyFunc(obj));
if (EqualityComparer != null)
{
var hash2 = EqualityComparer.GetHashCode(obj);
hash ^= (hash2 << 5) + hash2;
}
return hash;
}
/// <summary>
/// A key function.
/// </summary>
public readonly Func<T, K> KeyFunc;
/// <summary>
/// Optional base equality comparer.
/// </summary>
public readonly IEqualityComparer<T> EqualityComparer;
}
}
So, now you can easily build simple equality comparers to cache them or instantiate on the fly. This comparers are usually related to property values or their function of source values.
See also LINQ extensions
Dasha Nesterovsky
This is a small post about refactoring lock statements in async methods.
Before refactoring we had a code like this:
lock(sync)
{
result = methodToRefactorIntoAsync();
}
...
private object sync = new object();
Lock is bound to a thread, thus no way you to use it in async code. As an alternative you may use SemaphoreSlim class:
await sync.WaitAsync(cancellationToken);
try
{
result = await methodAsync(cancellationToken);
}
finally
{
sync.Release();
}
...
private SemaphoreSlim sync = new SemaphoreSlim(1, 1);
What will you do if you have async Web API method that runs on server for a some time but your client is dropped?
There are two solutions:
- Run method to the end and allow to a framework to deal with disconnect;
- Try to be notified about client's drop and to break early.
The first approach is simplest but might result in some overconsumption of server resources.
The other method requires you to check client status from time to time.
Fortunatelly, ASP.NET provides a HttpResponse.ClientDisconnectedToken property, which is limited to IIS 7.5+ in integrated mode, but still fits our needs.
So, you should request ClientDisconnectedToken , if any, and implement your async code using that token.
The following extension function gets that token:
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Threading;
using System.Web;
public static class HttpApiExtensions
{
public static CancellationToken GetCancellationToken(
this HttpRequestMessage request)
{
CancellationToken cancellationToken;
object value;
var key = typeof(HttpApiExtensions).Namespace + ":CancellationToken";
if (request.Properties.TryGetValue(key, out value))
{
return (CancellationToken)value;
}
var httpContext = HttpContext.Current;
if (httpContext != null)
{
var httpResponse = httpContext.Response;
if (httpResponse != null)
{
try
{
cancellationToken = httpResponse.ClientDisconnectedToken;
}
catch
{
// Do not support cancellation.
}
}
}
request.Properties[key] = cancellationToken;
return cancellationToken;
}
}
And here is a Web API WordCount service described in the previous post:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
public class ValuesController: ApiController
{
public async Task<int> GetWordCount([FromUri(Name = "url")] string[] urls)
{
var cancellationToken = Request.GetCancellationToken();
using(var client = new HttpClient())
{
return (await Task.WhenAll(
urls.Select(url => WordCountAsync(client, url, cancellationToken)))).Sum();
}
}
public static async Task<int> WordCountAsync(
HttpClient client,
string url,
CancellationToken cancellationToken)
{
string content = await (await client.GetAsync(url, cancellationToken)).
Content.ReadAsStringAsync();
return WordCount(content);
}
private static int WordCount(string text)
{
var count = 0;
var space = true;
for (var i = 0; i < text.Length; ++i)
{
if (space != char.IsWhiteSpace(text[i]))
{
space = !space;
if (!space)
{
++count;
}
}
}
return count;
}
}
Though is simple there is a nuisance. You should pass cancellation token here and there, which adds to a pollution from async .
Though parallel and async algorithms solve different tasks, they converge in some cases. And it's not always immediately clear what's the best.
Consider the following task: get a total word count contained in a given a set of urls.
At first we've solved it as a parallel task: indeed this fits to MapReduce pattern when you get urls' contents to count the number of words in parallel (Map), and then sum word counts per each url to get final result (Reduce).
But then we decided that the very same MapReduce algorithm can be implemented with async .
This is a parallel word count:
public static int ParallelWordCount(IEnumerable<string> urls)
{
var result = 0;
Parallel.ForEach(
urls,
url =>
{
string content;
using(var client = new WebClient())
{
content = client.DownloadString(url);
}
var count = WordCount(content);
Interlocked.Add(ref result, count);
});
return result;
}
Here is async word count:
public static async Task<int> WordCountAsync(IEnumerable<string> urls)
{
return (await Task.WhenAll(urls.Select(url => WordCountAsync(url)))).Sum();
}
public static async Task<int> WordCountAsync(string url)
{
string content;
using(var client = new WebClient())
{
content = await client.DownloadStringTaskAsync(url);
}
return WordCount(content);
}
And this is an implementation of word count for a text (it's less important for this discussion):
public static int WordCount(string text)
{
var count = 0;
var space = true;
for(var i = 0; i < text.Length; ++i)
{
if (space != char.IsWhiteSpace(text[i]))
{
space = !space;
if (!space)
{
++count;
}
}
}
return count;
}
Our impressions are:
The parallel version is contained in one method, while the async one is implemeneted with two methods.
This is due to the fact that C# compiler fails to generate async labmda function. We attribute this to Microsoft who leads and implements C# spec. Features should be composable. If one can implement a method as a lambda function, and one can implement a method as async then one should be able to implement a method as an async lambda function.
Both parallel and async versions are using thread pool to run their logic.
While both implementations follow MapReduce pattern, we can see that async version is much more scaleable. It's because of parallel threads stay blocked while waiting for an http response. On the other hand async tasks are not bound to any thread and are just not running while waiting for I/O.
This sample helped us to answer the question as to when to use parallel and when async . The simple answer goes like this:
- if your logic is only CPU bound then use parallel API;
- otherwise use
async API (this accounts I/O waits).
Not a long ago C# has introduced special language constructs to simplify asynchronous programming. It seems C++1x will follow async trend. But only recently when frameworks like ASP.NET Web API and Entity Framework started to catch up we've felt how it's to program with async and await keywords.
At first glance it seems it's a pure pleasure to write async methods:
private async Task SumPageSizesAsync()
{
// To use the HttpClient type in desktop apps, you must include a using directive and add a
// reference for the System.Net.Http namespace.
HttpClient client = new HttpClient();
// . . .
byte[] urlContents = await client.GetByteArrayAsync(url);
// . . .
}
To dereference a Task<T> into T you just write await task_t_expression , mark your method with async specifier, and adjust output type (if not void ) to Task or Task<Result> . Compiler applies its magic to convert your code into an asynchronous state machine.
We liked this feature and immediately have started to use it. But, as we said, async /await has shined in full when frameworks made it a core element, and at that point we have started to see that while async /await solve the task, they does not abstract the developer from implementation details, as a code gets considerably polluted.
Consider a method with pollution marked:
public static async Task<UserAuthorization> GetAuthorizationAsync(string accessToken)
{
var key = "oauth2:" + accessToken;
var authorization = cache.Get<UserAuthorization>(key);
if (authorization != null)
{
return authorization;
}
using(var model = new ModelContainer())
{
authorization =
(await model.UserAuthorizations.
Where(item => item.AccessToken == accessToken).
ToListAsync()).
FirstOrDefault();
}
if (authorization == null)
{
authorization = await ValidateAsync(accessToken);
}
cache.Set(key, cache.ShortDelay, authorization);
return authorization;
}
The more you use async , the more pollution you will see in your code. Ideally we would like to see the method quoted without any marked parts.
We needed to have oauth2 authorization in angularjs project.
Internet search on the subject immediately brings large amout of solutions like:
But unfortunatelly:
- provider specific libraries have too different set of APIs, which requires another umbrella library to allow for application to accept several providers;
- angular-oauth - supports Google only, and does not work in IE 11 with default security settings;
- oauth.io looks attractive but adds additional level of indirection server, and is free for a basic plan only.
However there is a problem with all those approaches.
Let's assume that you have properly implemented client side authorization, and finally have gotten an access_token .
Now, you access your server with that access_token . What is your first step on the server?
Right! Your should validate it against oauth2 provider.
So, while client side authorization, among other things, included a validation of your token, you have to perform the validation on the server once more.
At this point we felt that we need to implement our oauth2 API.
It can be found at nesterovsky-bros/oauth2.
This is the readme from that project:
Here we implement oauth2 authorization within angularjs.
Authentication is done as follows:
- Open oauth2 provider login/grant screen.
- Redirect to the oauth2 callback screen with access token.
- Verify of the access token against provider.
- Get some basic profile.
A base javascript class OAuth2 implements these steps.
There are following implementations that authorize against specific providers:
OAuth2Server - implements authorization through known providers, but calls server side to validate access token. This way, the server side can establish a user's session.
The file Config.json contains endpoints and request parameters per supported provider.
Note: You should register a client_id for each provider.
Note: user_id and access_tokens are unique only in a scope of access provider, thus a session is identified by Provider + access_token, and a user is identified by Provider + user_id.
The use case can be found in test.js E.g. authorization against OAuth2Server is done like this:
var login = new OAuth2Server(provider);
token = login.authorize();
token.$promise.then(
function()
{
// token contains populated data.
},
function(error)
{
if (error)
{
// handle an error
}
});
Authorization token contains:
- a promise to handle authorization outcome.
- cancelToken (a Deferred object) to cancel authorization in progress.
Whole sample is implemented as VS project. All scripts are build with app.tt, that combines content of Scripts/app int app.js.
Server side is implemented with ASP.NET Web API. Authorization controllers are:
After several years of experience with KendoUI we turned our attention to AngularJS. As many other libraries it has its strong and weak sides. There are many resources describing what AngularJS is, and what it is not. Our approach to study AngularJS was through an attempt to integrate it into an existing KendoUI web application.
It's rather straightforward to convert model from KendoUI into AngularJS, as logically both frameworks are equal in this regard. But tactically KendoUI implements model-view binding very differently than AngularJS does. KendoUI binds model to view immediately per each model field, where AngularJS delays a binding of each model field and performs whole model binding in one go. Angular's approach is more performant, and even more appealing to a developer, though the problem is that the time it takes to make whole model binding is proportional to a size (number of objects and properties) of model. This means that if you have a relatively big model you will experience tangible halts in browser's UI while a javascript updating view/model is running.
AngularJS advices some workaround, which in essence is to avoid big model. The problem is that a couple of thousands or even several hundrends of objects and properties are already considered big model. So, you should immediately plan your model, and view to avoid any potential impact. This seriously distracts from the task your're solving.
The idea that your UI will halt for the time proportional to the size of your whole model looks flawed in our opinion. KendoUI knows no such a problem. That's the reason why our KendoUI to AngularJS transition experience was not smooth.
Our analysis of AngularJS sources shows that the issue could be resolved provided model to view binding (it's called digest in that library) was asynchronous.
To verify our ideas we have created a branch nesterovsky-bros/angular.js where we implemented required refactorings. It includes:
-
API based on existing deferred/promise to write algorithms in async way, and
- refactored digest logic.
At the end we have proposed to integrate our changes into the main branch: Make $digest async.
We're not sure whether our proposition will be integrated (rather no than yes). Nevertheless what we have come with is an interesting extension of deferred object that we neither have seen in AngularJS nor in JQuery, so later we will quote that API from q.js and scheduler.js.
Among proposed new features (other than Maps and Arrays) in XPath 3.1 we like Arrow operator (=>).
It's defined like this:
[Definition: An arrow operator is a postfix operator that applies a function to an item, using the item as the first argument to the function.] If $i is an item and f() is a function, then $i=>f() is equivalent to f($i) , and $i=>f($j) is equivalent to f($i, $j) .
This syntax is particularly helpful when conventional function call syntax is unreadable, e.g. when applying multiple functions to an item. For instance, the following expression is difficult to read due to the nesting of parentheses, and invites syntax errors due to unbalanced parentheses:
tokenize((normalize-unicode(upper-case($string))),"\s+")
Many people consider the following expression easier to read, and it is much easier to see that the parentheses are balanced:
$string=>upper-case()=>normalize-unicode()=>tokenize("\s+")
What it looks like?
Right! It's like extension functions in C#.
In the article "Error handling in WCF based web applications"
we've shown a custom error handler for RESTful service
based on WCF. This time we shall do the same for Web API 2.1 service.
Web API 2.1 provides an elegant way to implementat custom error handlers/loggers, see
the following article. Web API permits many error loggers followed by a
single error handler for all uncaught exceptions. A default error handler knows to output an error both in XML and JSON formats depending on requested
MIME type.
In our projects we use unique error reference IDs. This feature allows to an end-user to refer to any error that has happened during the application life time and pass such error ID to the technical support for further investigations. Thus, error details passed to the client-side contain an ErrorID field. An error logger generates ErrorID and passes it over to an error handler for serialization.
Let's look at our error handling implementation for a Web API application.
The first part is an implementation of IExceptionLogger
interface. It assigns ErrorID and logs all errors:
/// Defines a global logger for unhandled exceptions.
public class GlobalExceptionLogger : ExceptionLogger
{
/// Writes log record to the database synchronously.
public override void Log(ExceptionLoggerContext context)
{
try
{
var request = context.Request;
var exception = context.Exception;
var id = LogError(
request.RequestUri.ToString(),
context.RequestContext == null ?
null : context.RequestContext.Principal.Identity.Name,
request.ToString(),
exception.Message,
exception.StackTrace);
// associates retrieved error ID with the current exception
exception.Data["NesterovskyBros:id"] = id;
}
catch
{
// logger shouldn't throw an exception!!!
}
}
// in the real life this method may store all relevant info into a database.
private long LogError(
string address,
string userid,
string request,
string message,
string stackTrace)
{
...
}
}
The second part is the implementation of IExceptionHandler :
/// Defines a global handler for unhandled exceptions.
public class GlobalExceptionHandler : ExceptionHandler
{
/// This core method should implement custom error handling, if any.
/// It determines how an exception will be serialized for client-side processing.
public override void Handle(ExceptionHandlerContext context)
{
var requestContext = context.RequestContext;
var config = requestContext.Configuration;
context.Result = new ErrorResult(
context.Exception,
requestContext == null ? false : requestContext.IncludeErrorDetail,
config.Services.GetContentNegotiator(),
context.Request,
config.Formatters);
}
/// An implementation of IHttpActionResult interface.
private class ErrorResult : ExceptionResult
{
public ErrorResult(
Exception exception,
bool includeErrorDetail,
IContentNegotiator negotiator,
HttpRequestMessage request,
IEnumerable<MediaTypeFormatter> formatters) :
base(exception, includeErrorDetail, negotiator, request, formatters)
{
}
/// Creates an HttpResponseMessage instance asynchronously.
/// This method determines how a HttpResponseMessage content will look like.
public override Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var content = new HttpError(Exception, IncludeErrorDetail);
// define an additional content field with name "ErrorID"
content.Add("ErrorID", Exception.Data["NesterovskyBros:id"] as long?);
var result =
ContentNegotiator.Negotiate(typeof(HttpError), Request, Formatters);
var message = new HttpResponseMessage
{
RequestMessage = Request,
StatusCode = result == null ?
HttpStatusCode.NotAcceptable : HttpStatusCode.InternalServerError
};
if (result != null)
{
try
{
// serializes the HttpError instance either to JSON or to XML
// depend on requested by the client MIME type.
message.Content = new ObjectContent<HttpError>(
content,
result.Formatter,
result.MediaType);
}
catch
{
message.Dispose();
throw;
}
}
return Task.FromResult(message);
}
}
}
Last, but not least part of this solution is registration and configuration of the error logger/handler:
/// WebApi congiguation.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
...
// register the exception logger and handler
config.Services.Add(typeof(IExceptionLogger), new GlobalExceptionLogger());
config.Services.Replace(typeof(IExceptionHandler), new GlobalExceptionHandler());
// set error detail policy according with value from Web.config
var customErrors =
(CustomErrorsSection)ConfigurationManager.GetSection("system.web/customErrors");
if (customErrors != null)
{
switch (customErrors.Mode)
{
case CustomErrorsMode.RemoteOnly:
{
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.LocalOnly;
break;
}
case CustomErrorsMode.On:
{
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Never;
break;
}
case CustomErrorsMode.Off:
{
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
break;
}
default:
{
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Default;
break;
}
}
}
}
}
The client-side error handler remain almost untouched. The implementation details you may find in
/Scripts/api/api.js and Scripts/controls/error.js files.
You may download the demo project here.
Feel free to use this solution in your .NET projects.
From time to time we run into tasks that we would like to solve in LINQ style but unfortunately it either cannot be done or a solution is not efficient.
Note that by LINQ style we do not mean C# query expressions (we have a strong distaste for that syntax) but extension methods defined in System.Linq.Enumerable and other classes.
Here we quote several extension methods that are good for a general use:
1. Select with predicate. This is shorthand of items.Where(...).Select(...) :
/// <summary>
/// Projects each element of a sequence into a new form.
/// </summary>
/// <typeparam name="T">A type of elements of source sequence.</typeparam>
/// <typeparam name="R">A type of elements of target sequence.</typeparam>
/// <param name="source">A source sequence.</param>
/// <param name="where">A predicate to filter elements.</param>
/// <param name="selector">A result element selector.</param>
/// <returns>A target sequence.</returns>
public static IEnumerable<R> Select<T, R>(
this IEnumerable<T> source,
Func<T, bool> where,
Func<T, R> selector)
{
return source.Where(where).Select(selector);
}
2. Select with predicate with source element index passed both into the predicate and into the selector. This one you cannot trivially implement in LINQ:
/// <summary>
/// Projects each element of a sequence into a new form.
/// </summary>
/// <typeparam name="T">A type of elements of source sequence.</typeparam>
/// <typeparam name="R">A type of elements of target sequence.</typeparam>
/// <param name="source">A source sequence.</param>
/// <param name="where">A predicate to filter elements.</param>
/// <param name="selector">A result element selector.</param>
/// <returns>A target sequence.</returns>
public static IEnumerable<R> Select<T, R>(
this IEnumerable<T> source,
Func<T, int, bool> where,
Func<T, int, R> selector)
{
var index = 0;
foreach(var value in source)
{
if (where(value, index))
{
yield return selector(value, index);
}
++index;
}
}
3. A function with output element as projection of a window of input elements. Such function can be used to get finite difference (operation opposite to a cumulative sum).
/// <summary>
/// Projects a window of source elements in a source sequence into target sequence.
/// Thus
/// target[i] =
/// selector(source[i], source[i - 1], ... source[i - window + 1])
/// </summary>
/// <typeparam name="T">A type of elements of source sequence.</typeparam>
/// <typeparam name="R">A type of elements of target sequence.</typeparam>
/// <param name="source">A source sequence.</param>
/// <param name="window">A size of window.</param>
/// <param name="lookbehind">
/// Indicate whether to produce target if the number of source elements
/// preceeding the current is less than the window size.
/// </param>
/// <param name="lookahead">
/// Indicate whether to produce target if the number of source elements
/// following current is less than the window size.
/// </param>
/// <param name="selector">
/// A selector that derives target element.
/// On input it receives:
/// an array of source elements stored in round-robing fashon;
/// an index of the first element;
/// a number of elements in the array to count.
/// </param>
/// <returns>Returns a sequence of target elements.</returns>
public static IEnumerable<R> Window<T, R>(
this IEnumerable<T> source,
int window,
bool lookbehind,
bool lookahead,
Func<T[], int, int, R> selector)
{
var buffer = new T[window];
var index = 0;
var count = 0;
foreach(var value in source)
{
if (count < window)
{
buffer[count++] = value;
if (lookbehind || (count == window))
{
yield return selector(buffer, 0, count);
}
}
else
{
buffer[index] = value;
index = index + 1 == window ? 0 : index + 1;
yield return selector(buffer, index, count);
}
}
if (lookahead)
{
while(--count > 0)
{
index = index + 1 == window ? 0 : index + 1;
yield return selector(buffer, index, count);
}
}
}
This way a finite difference looks like this:
var diff = input.Window(
2,
false,
false,
(buffer, index, count) => buffer[index ^ 1] - buffer[index]);
4. A specialization of Window method that returns a enumeration of windows:
/// <summary>
/// Projects a window of source elements in a source sequence into a
/// sequence of window arrays.
/// </summary>
/// <typeparam name="T">A type of elements of source sequence.</typeparam>
/// <typeparam name="R">A type of elements of target sequence.</typeparam>
/// <param name="source">A source sequence.</param>
/// <param name="window">A size of window.</param>
/// <param name="lookbehind">
/// Indicate whether to produce target if the number of source elements
/// preceeding the current is less than the window size.
/// </param>
/// <param name="lookahead">
/// Indicate whether to produce target if the number of source elements
/// following current is less than the window size.
/// </param>
/// <returns>Returns a sequence of windows.</returns>
public static IEnumerable<T[]> Window<T>(
this IEnumerable<T> source,
int window,
bool lookbehind,
bool lookahead)
{
return source.Window(
window,
lookbehind,
lookahead,
(buffer, index, count) =>
{
var result = new T[count];
for(var i = 0; i < count; ++i)
{
result[i] = buffer[index];
index = index + 1 == buffer.Length ? 0 : index + 1;
}
return result;
});
}
While writing an article Dealing with dynamic SQL in SQL Server we have crushed on a trivial C# code.
Consider a declaration:
public enum Direction
{
Asc,
Desc
}
public struct Order
{
public string Field { get; set; }
public Direction Direction { get; set; }
}
public class DateRange
{
public DateTime? From { get; set; }
public DateTime? To { get; set; }
}
public class Request
{
public DateRange CreatedAt { get; set; }
public string Summary { get; set; }
[XmlElement]
public int[] State { get; set; }
public DateRange UpdatedAt { get; set; }
[XmlElement]
public Order[] Order { get; set; }
}
and a code:
...
var request = new Request
{
CreatedAt = { From = new DateTime(2014, 1, 1) },
Order = new[]
{
new Order { Field = "CreatedAt" }
}
};
...
It was hard to believe that this simple variable declaration throws NullReferenceException .
In fact we could not realize what the reason is until we have decompiled that code and poked into IL.
It appears that the problem is with the line:
CreatedAt = { From = new DateTime(2014, 1, 1) },
It's implemented like this:
var range = request.CreatedAt;
range.From = new DateTime(2014, 1, 1) ;
range.To = null;
In other words it assumes the instance stored in property CreatedAt is not null , and it reinitializes all its properties.
In contrast the following works as expected (no exception is thrown):
CreatedAt = new { From = new DateTime(2014, 1, 1) },
as it creates a new instance and assigns it to a property.
We think that this is very error prone, so if it's how C# is assumed to be then it's the problem of the spec, otherwise it's the problem of Microsoft implementation of C# (at least in VS 2010 - 2013).
|