Thursday, December 12, 2019

Handling PubSub updates from multiple clients in pub-sub scenario with Reactive Extentions

A typical pub-sub scenario is subscribing to handle requests from multiple clients and then handling client updates in a buffered way. Let's see how this could be done using Reactive Extensions.

To make this scenario more concrete - imagine your server receives a stream of frequent updates on number of stocks (e.g. IBM_1...IBM_10 in example below). We want to process the most recent price per stock and display it to a trader at most once a second.

All we would need - is to use ReactivePubSubHandler given below, providing "selector" to identify a pub-sub client (i.e. what stock was updated) and an action to be implemented (e.g. update price display) - say once in a second.



using System;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Threading;

namespace ReactivePubSub
{
    class Program
    {
        class ClientUpdate
        {
            public string StockName { getset; }
            public float Price { getset; }
        }

        static void Main()
        {
            var sampledAction = new ReactivePubSubHandler<ClientUpdatestring>(1000, _=>_.StockName, _ => Console.WriteLine(
                $"{DateTime.Now} Processed update for client #{_.StockName} Price={_.Price}"));

            var rndStockName = new Random();
            
            for (int i = 0; i < 1000; i++)
            {
                var clientUpdate = new ClientUpdate()
                {
                    StockName = "IBM_" + rndStockName.Next(0, 10),
                    Price = (float) (rndStockName.Next(10000, 11000) / 100.0)
                };
                sampledAction.OnClientRequest(clientUpdate);
                Thread.Sleep(200);
            }
        }
    }

    public class ReactivePubSubHandler<TClientDataTClientDataKey>
    {
        public ReactivePubSubHandler(int sampleIntervalMs, Func<TClientDataTClientDataKey> pubSubTopicSelector, Action<TClientData> pubSubAction)
        {
            var sampledActionsSubscription = _clientsSubscription.GroupBy(pubSubTopicSelector)
                .Select(x => x.Sample(TimeSpan.FromMilliseconds(sampleIntervalMs))).SelectMany(x => x);
            sampledActionsSubscription.Subscribe(pubSubAction);
        }

        public void OnClientRequest(TClientData clientData)
        {
            _clientsSubscription.OnNext(clientData);
        }

        private readonly Subject<TClientData> _clientsSubscription = new Subject<TClientData>();
    }
}

Wednesday, November 07, 2018

Compiling QuantLib with Visual Studio 2017 and boost 1.68

This post is a self-reminder.
Once QuantLib binaries are created as described below - you should reference .NET assembly (NQuantLib.dll) and have native .Dll (NQuantLibc.dll) to be added as a Context file with "Copy always" attribute in "Copy to Output directory".
Compiling QuantLib for Visual Studio 2017
1.     Make sure VS 2017 setup installed with Windows 8.1 SDK:

2.     Download pre-compiled boost library for VC 14 (x64 version) from https://sourceforge.net/projects/boost/files/boost-binaries/1.68.0/
  Install boost binaries boost_1_68_0-msvc-14.1-64.exe to C:\Boost\boost_1_68_0
3.    Add C:\Boost\boost_current.props file (e.g. download from https://github.com/Studiofreya/boost-build-scripts/), e.g.:


5.    Unpack SWIG to C:\SWIG\swigwin-3.0.12
6.    Add C:\SWIG\swigwin-3.0.12 to system PATH environment variable
7.    Unpack QuantLib to C:\QuantLib\QuantLib-1.13
8.    Unpack QuantLib-SWIG to C:\QuantLib\QuantLib-SWIG-1.13
9.    Modify  C:\QuantLib\QuantLib-1.13\QuantLib.props by including the following section:
   
 

10.  Enable (uncomment) QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN in ql\userconfig.hpp file
11.  Build QuantLib.sln
12.  Run the swig.cmd file located in QuantLib-SWIG\CSharp folder
13.  Modify C:\QuantLib\QuantLib-SWIG-1.13\CSharp\QuantLib.props by including the following section:

















14.  Build C:\QuantLib\QuantLib-SWIG-1.13\CSharp\QuantLib.sln
15.  Use the following residuals:
·         C:\QuantLib\QuantLib-SWIG-1.13\CSharp\cpp\bin\vc141\x64\Debug\NQuantLibc.dll
·         C:\QuantLib\QuantLib-SWIG-1.13\CSharp\cpp\bin\vc141\x64\Debug\QuantlibWrapper.pdb
·         C:\QuantLib\QuantLib-SWIG-1.13\CSharp\csharp\bin\vc141\x64\Debug\NQuantLib.dll
·         C:\QuantLib\QuantLib-SWIG-1.13\CSharp\csharp\bin\vc141\x64\Debug\NQuantLib.pdb

Monday, December 24, 2012

Monday, May 07, 2012

GC KeepAlive method–what it really does

Quite useful, I was missing this corner..
Below is quote from documentation as it is provided by code author.



// This method DOES NOT DO ANYTHING in and of itself.  It's used to
// prevent a finalizable object from losing any outstanding references
// a touch too early. The JIT is very aggressive about keeping an
// object's lifetime to as small a window as possible, to the point
// where a 'this' pointer isn't considered live in an instance method
// unless you read a value from the instance. So for finalizable
// objects that store a handle or pointer and provide a finalizer that
// cleans them up, this can cause subtle ----s with the finalizer
// thread. This isn't just about handles - it can happen with just
// about any finalizable resource.
//
// Users should insert a call to this method near the end of a
// method where they must keep an object alive for the duration of that
// method, up until this method is called. Here is an example:
//
// "...all you really need is one object with a Finalize method, and a
// second object with a Close/Dispose/Done method. Such as the following
// contrived example:
//
// class Foo {
// Stream stream = ...;
// protected void Finalize() { stream.Close(); }
// void Problem() { stream.MethodThatSpansGCs(); }
// static void Main() { new Foo().Problem(); }
// }
//
//
// In this code, Foo will be finalized in the middle of
// stream.MethodThatSpansGCs, thus closing a stream still in use."
//
// If we insert a call to GC.KeepAlive(this) at the end of Problem(), then
// Foo doesn't get finalized and the stream says open.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern void KeepAlive(Object obj);

Sunday, April 08, 2012

Get user name in SQL

… without domain:

SELECT PARSENAME(REPLACE(ORIGINAL_LOGIN(), '\', '.'), 1)

Currencies having stocks quoted in cents

I think this is exhaustive list for now:

BWp Botswana Pula
GBp British Pound
ILs Israeli Shekel
KWd Kuwaiti Dinar
MWk Malawian Kwacha
SZl Swaziland Lilangeni
ZAr South African Rand

“267: The directory name is invalid” error when running via runas command

Should be one of:

  • User Access Control settings prevent you from executing a program
  • Directory has no access for user which is specified in runas
  • You shared your folder and that reset user rights on the folder –
    go to Properties->Security and add runas user..