Lastly, I have decided to create a new library for .NET core that handles (big) prime numbers. You know - testing, generating and other stuff that could be useful for playing with big numbers.
It is obvious that to accomplish this, I needed a service that should generate a bunch of random values. Easy task? Yep!
Random provider
The only method I need is to generate random bytes that are placed in a buffer - our numbers could much more beyond int/long range, so I have decided to represent numbers as the byte array (like BigInteger it does).
Random provider is used to generate random big integer below a specified range, fe.
See snippet below:
publicclassBigIntegerGenerator{publicTask<BigInteger>GenerateNonZeroAsync(BigIntegermaxExclusive){varrndProvider=newSimpleRandomProvider();varbuffer=maxExclusive.ToByteArray();if(maxExclusive<int.MaxValue){//special case, not relevant//generate simple int etcreturn;}returnTask.Run(()=>{BigIntegerresult;do{rndProvider.NextBytes(buffer);bytes[bytes.Length-1]&=0x7F;//ensure positiveresult=newBigInteger(bytes);}while(result>=maxExclusive||result==0);returnresult;});}}
Like a model programmer, I wrote some unit tests ran by xUnit:
Disclaimer: Tests are simple as possible to simplify the case.
I have ran my tests and… Testing has never ever finished. Or even failed. Just like an endless loop.
What went wrong
I have spent couple hours to find out the cause of this weird behavior (my tests % snippets are much more complicated).
Indeed, the problem was an endless loop… here:
Yeep!
It turned out, that xUnit runs tests in separate threads. What’s more, Random.NextBytes is not threadsafe, so… it started to fill bytes with 0 when more than one thread accessed it at the same time.
classLogUserEvents:IUserEvent{publicvoidCreate(stringid){someLogger.Log($"User { id } created");}publicvoidUpdated(stringid){someLogger.Log($"User { id } updated");}}
And… that’s all! The Event bus system automatically searches for implementations, resolves it with the current dependency resolver and calls proper methods. Magic!
How Can I achieve it?
The first step is to create a proxy class for interfaces, that automatically invokes all implementations. I have used Castle.DynamicProxy for it:
publicclassMultiInterfaceProxy:IInterceptor{privatereadonlyLazy<IEnumerable<IEvent>>events;privateMultiInterfaceProxy(TypeeventType,IImplementationProviderimplementationProvider){this.events=implementationProvider.For(eventType);}privateIEnumerable<IEvent>Events{get{returnthis.events.Value;}}publicstaticobjectFor(TypeeventType,IImplementationProviderimplementationProvider){if(!eventType.IsInterface)thrownewArgumentException("Event must be an interface.","eventType");if(!typeof(IEvent).IsAssignableFrom(eventType))thrownewArgumentException("Event must be derrived from IEvent","eventType");vargenerator=newProxyGenerator();varproxtInterceptor=newMultiInterfaceProxy(eventType,implementationProvider);returngenerator.CreateInterfaceProxyWithoutTarget(eventType,proxtInterceptor);}publicvoidIntercept(IInvocationinvocation){varreturnType=invocation.Method.ReturnType;if(returnType.IsGenericType&&typeof(IEnumerable<>).IsAssignableFrom(returnType.GetGenericTypeDefinition())){this.InvokeWithEnumerableReturn(invocation,returnType);}elseif(returnType==typeof(Task)){this.HandleTask(invocation);}else{this.InvokeVoid(invocation);}}privatevoidHandleTask(IInvocationinvocation){vartasks=this.Events.Select(ev=>(Task)invocation.Method.Invoke(ev,invocation.Arguments)).ToArray();invocation.ReturnValue=Task.Factory.StartNew(()=>Task.WaitAll(tasks));}privatevoidInvokeVoid(IInvocationinvocation){objectresult=null;foreach(var@eventinthis.Events){try{result=invocation.Method.Invoke(@event,invocation.Arguments);}catch(Exceptionex){HandleException(ex,@event);}}invocation.ReturnValue=result;}privatevoidInvokeWithEnumerableReturn(IInvocationinvocation,TypereturnType){varlist=(IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(returnType.GetGenericArguments()[0]));foreach(var@eventinthis.Events){try{varenumerable=(IEnumerable)invocation.Method.Invoke(@event,invocation.Arguments);if(enumerable==null){continue;}varenumerator=enumerable.GetEnumerator();while(enumerator.MoveNext()){list.Add(enumerator.Current);}}catch(Exceptionex){HandleException(ex,@event);}}invocation.ReturnValue=list;}privatestaticvoidHandleException(Exceptionex,IEventproxiedEvent){if(!(exisTargetInvocationException)){throwex;}vartex=ex.InnerException;if(tex==null){throwex;}if(!(texisEventFatalException)&&!proxiedEvent.IsAlwaysFatal()){return;}if(tex.InnerException!=null){tex=tex.InnerException;}throwtex;}}
(part of classes are skipped).
But alone proxy is not enough - we need to integrate it with some dependency injection library.
I have chosen my favourite - AutoFac:
First of all - If you have such a situation - your design of architecture is bad. I’m almost sure that problem can be solved by changing structure of your classes.
I’m stubborn / I don’t want to change my class design / I just want to know the answer
How does it work? Dynamic forces to resolve type at runtime, so proper overload will be chosen. Main drawback? If you forget to prepare overload for type, you will get runtime binder-exception.
Generic invoker
To get benefit from dynamic and if approach I have prepared small library with Fluent API:
If you are developing with Unity 3D, coroutines are part of your life. Exceptions are also. It sounds trivial, but it is not easy to bring together both of these things.
Consider:
In a previous blog I have written about my mini-PC that was setup as the server. I have decided to move everything from OneDrive (my OneDrive space was limited from 30 Gb to 7 due to last Microsft rule changes) The most known self-hosted solution is ownCloud. Written in PHP, easy to install - it just fits requirements. Unfortunately, it turned out that the newest version has no Windows support (via FastCGI).
After digging somewhere on the internet I have found syncthing. It offers an alternative approach. There is no central server - everything is based on distributed sharing. Dedicated client for windows (client app is server itself), easy install. So what is the problem? Imagine the situation, when you are at friend’s home. You need to download the file from your cloud. A friend didn’t know about syncthing before. So you need to download the app, allow new client to “join” your devices network and viola. There is no web client that could be very use full in some scenarios.
I could not find any 3rd solutions that could offer some PHP-or-whatever site to integrate with the new cloud. But wait. I’m a programmer!
Syncting Web UI
Syncthing Web UI is web app that reads metadata from syncthing config file and offers basic functionality as web client:
Welcome to my new blog. As you can remember, the old one was setup for DajSięPoznać contest. A quality of posts was low (sic!) so I decided to start from the scratch. No posts will be moved (unless I find some time) but believe me - there is no good content to read ;)
Current blog was setup with jekyll so speed of page load should be like a thunder.
How do you like a dbyll theme?