300x250 AD TOP

Search This Blog

Pages

Paling Dilihat

Powered by Blogger.

Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, September 14, 2012

Many Files Concurrent Read/Write

As part of an optimization I needed to do to a heavily loaded application I've searched for a way to read and write a lot of small to medium sized files, it was one more serious bottleneck which good caching alleviated but did not eliminate due to the amount of the files going out of cache.

So I've thought about 3 ways of accessing files and went ahead to see which one is faster, the first one will attempt to read/write with exception handling, the second one will use a queue with worker threads and the third one will avoid trying to access the files if they exist in a read/write dictionary (multiple reads are allowed but only one write).

At a later stage I've added the dictionary check to the queue, to make it more efficient, if a specific file is writing, the 2nd attempt will be re-queued so other files can be cleared out of the queue.

The results are files per second, for 50k files, 1000 random iterations on 100  files range averaged on 10 executions



ActionThreadsOS LockingQueued 1Queued 2Avoid
Read19775 1000 990 10193
Read531887 15019 14560 31585
Read1038639 15669 1066036886
Write13017 1022 993 2791
Write55532 4857 4766 5413
Write105378 4866 4625 5339
Read/Write14504 1050 995 5173
Read/Write510477 6934 7711 10324
Read/Write109742 7867 7824 10773

The results are pretty straight forward, OS Locking uses exceptions for handling collisions, it makes it slower in one thread, but it is overall faster because there are no overheads from other elements.


I've written two queued classes, one of them is invoking a method on each queue item, the other is in a continuous loop, the continuous loop is faster.

Overall it seems that avoiding an OS file access is the same as the exception for attempting to access the same file except when the file operation takes a long time, this is probably due to the fact that the method will keep trying every 1 ms to access the file in case of "file in use" exception, wasting CPU instead of waiting peacefully for the file to be unlocked.

Its been an interesting test for me, I've thought that the queues will do a much faster job as the OS will need only to handle writing and reading files sequentially, I was wrong and it was good to find out.

I'm including all the source code for the tests, I have a feeling the DictionaryLock and the QueuedExecution will find a better use in the future.

The DictionaryLock uses ConcurrentDictionary and a SpinLock to perform a Read/Write lock on keys, the spinlock is there so only one thread will be able to insert new locks into the dictionary.


/// <summary>
/// Dictionary of locks on TKey
/// </summary>
/// <typeparam name="TKey">Type of key</typeparam>
public class DictionaryLock<TKey>
{
    /// <summary>
    /// Dictionary of locks container
    /// </summary>
    private ConcurrentDictionary<TKey, ReaderWriterLockSlim> _locks = new ConcurrentDictionary<TKey, ReaderWriterLockSlim>();

    /// <summary>
    /// _locks updating lock
    /// </summary>
    private SpinLock _operationlock = new SpinLock();

    /// <summary>
    /// Retrieves the ReaderWriterLock for a specific key
    /// </summary>
    private ReaderWriterLockSlim GetLock(TKey key)
    {
        //check if lock exist
        ReaderWriterLockSlim localock;
        if (_locks.TryGetValue(key, out localock))
        {
            return localock;
        }

        //it doesn't exist, lets create it

        bool lockTaken = false;
        _operationlock.Enter(ref lockTaken);

        //after acquired write lock, recheck its not in the dictionary if two writes were attempted for the same key
        if (!_locks.TryGetValue(key, out localock))
        {
            localock = new ReaderWriterLockSlim();
            _locks[key] = localock;
        }
        _operationlock.Exit();

        return localock;
    }


    /// <summary>
    /// Enter Reader lock on key
    /// </summary>
    public void EnterReader(TKey key)
    {
        var localock = GetLock(key);

        localock.EnterReadLock();
    }

    /// <summary>
    /// Enter Writer lock on key
    /// </summary>
    public void EnterWriter(TKey key)
    {
        var localock = GetLock(key);

        localock.EnterWriteLock();
    }

    /// <summary>
    /// Check Reader locked on key
    /// </summary>
    public bool IsReaderLocked(TKey key)
    {
        ReaderWriterLockSlim localock;
        if (_locks.TryGetValue(key, out localock))
            return localock.IsReadLockHeld;
        return false;
    }

    /// <summary>
    /// Check Writer locked on key
    /// </summary>
    public bool IsWriterLocked(TKey key)
    {
        ReaderWriterLockSlim localock;
        if (_locks.TryGetValue(key, out localock))
            return localock.IsWriteLockHeld;
        return false;
    }

    /// <summary>
    /// Exit Reader lock on key
    /// </summary>
    public void ExitReader(TKey key)
    {
        ReaderWriterLockSlim localock;
        if (_locks.TryGetValue(key, out localock))
            localock.ExitReadLock();
    }

    /// <summary>
    /// Exit Writer lock on key
    /// </summary>
    public void ExitWriter(TKey key)
    {
        ReaderWriterLockSlim localock;
        if (_locks.TryGetValue(key, out localock))
            localock.ExitWriteLock();
    }
}


The QueuedExecution is an abstract class providing an easy way to implement queued object handling, it uses the ManualResetEventSlim to notify the caller its done processing the request, it could use a better exception handling, I've done the minimum for this test project.


/// <summary>
/// Abstract Queued Execution
/// <para>Provides infrastructure for executing IItems with ProcessQueue override
/// in a number of threads in defined in the constructor</para>
/// </summary>
public abstract class QueuedExecution : IDisposable
{
    /// <summary>
    /// Process Result, returned by ProcessQueue
    /// </summary>
    protected enum ProcessResult
    {
        Success,
        FailThrow,
        FailRequeue
    }

    /// <summary>
    /// Item interface
    /// </summary>
    protected interface IItem {}

    /// <summary>
    /// Queue Item container
    /// </summary>
    private class QueueItem
    {
        /// <summary>
        /// IItem
        /// </summary>
        public IItem Item { get; set; }

        /// <summary>
        /// Result of ProcessQueue
        /// </summary>
        public ProcessResult ProcessResult { get; set; }

        /// <summary>
        /// ManualResetEvent for pinging back the waiting call
        /// </summary>
        public ManualResetEventSlim resetEvent { get; set; } 
    }

    /// <summary>
    /// Queue containing all the items for execution
    /// </summary>
    private ConcurrentQueue<QueueItem> _queue = new ConcurrentQueue<QueueItem>();

    /// <summary>
    /// Process Queue method, should be overriden in inheriting class
    /// </summary>
    /// <param name="item">item to be executed against</param>
    /// <returns>success/fail/requeue</returns>
    protected abstract ProcessResult ProcessQueue(IItem item);

    /// <summary>
    /// Number of threads to process queue
    /// </summary>
    private int _threadcount = 1;

    /// <summary>
    /// Threads array
    /// </summary>
    private Thread[] _threads;

    /// <summary>
    /// flag, should abort all executing threads
    /// </summary>
    private bool _threadaborted = false;

    /// <summary>
    /// Initializes the threads for execution
    /// </summary>
    private void Initialize()
    {
        _threads = new Thread[_threadcount];
        for (var i = 0; i < _threadcount; i++)
            _threads[i] = new Thread(new ThreadStart(() =>
                {
                    do
                    {
                        QueueItem item;
                        if (_queue.TryDequeue(out item))
                        {
                            item.ProcessResult = ProcessQueue(item.Item);

                            if (item.ProcessResult == ProcessResult.FailRequeue)
                            {
                                _queue.Enqueue(item);
                                continue;
                            }

                            item.resetEvent.Set();
                        }
                        else
                        {
                            Thread.Sleep(1);
                        }
                    } while (!_threadaborted);
                }));
        for (var i = 0; i < _threadcount; i++)
            _threads[i].Start();
    }

    protected QueuedExecution(int threads)
    {
        _threadcount = threads;
        Initialize();
    }

    /// <summary>
    /// Execute call in queue, block until processed
    /// </summary>
    /// <param name="item"></param>
    protected void Execute(IItem item)
    {
        var resetevent = new ManualResetEventSlim();
        var qi = new QueueItem
            {
                Item = item,
                resetEvent = resetevent
            };
        _queue.Enqueue(qi);
        resetevent.Wait();

        if (qi.ProcessResult == ProcessResult.FailThrow)
            throw new Exception("execution failed");
    }

    #region IDisposable Members

    /// <summary>
    /// cleanup
    /// </summary>
    /// <param name="waitForFinish">should wait for process to finish 
    /// currently executing request or abort immediately</param>
    /// <param name="wait">time to wait for abort to finish</param>
    public void Dispose(bool waitForFinish,TimeSpan wait)
    {
        _threadaborted = true;
         bool allaborted = true;
        if (waitForFinish)
        {
            //wait for timeout, check if threads aborted gracefully in that time
            while ((DateTime.Now + wait) > DateTime.Now)
            {
                allaborted = true;
                foreach (var t in _threads)
                {
                    if (t.IsAlive == true)
                    {
                        allaborted = false;
                        break;
                    }
                }
                if (allaborted == true)
                    break;

                Thread.Sleep(1);
            }
        }

        //if not all threads were aborted, abort them
        if (allaborted == false)
        {
            foreach (var t in _threads)
                if (t.IsAlive)
                    t.Abort();
        }
    }

    public void Dispose()
    {
        Dispose(false,TimeSpan.MinValue);
    }

    #endregion
}


You can find the source code here:
https://github.com/drorgl/ForBlog/tree/master/FileCollisionTests
Tags: , , ,

Tuesday, August 21, 2012

NVelocity Template Engine

Note: The NVelocity project was abandoned in 2009, I've wanted to write this article back in November 2010, but I've found a few minutes only recently and in the hope its not a complete waste of time, here you have it with a some modifications and updates.

Velocity was one of the more advanced string templating engines around that time, it didn't take long to port it to .NET which became NVelocity. if you're porting an old application and need a transition time that all your templates will work before you can convert them to one of the more recent and advanced templating engines such as Razor, you may have found the demo program you needed.

I've tried both Castle NVelocity and Terri Liang's NVelocity port, I'm not sure which came before which, if one is an improvement of the other, but I needed something that supports recursive macros and string templates (instead of file/resource templates) which Castle didn't, so I've used the one from Terri Liang, which did.

Apache's velocity has the documentation for the syntax.

First instantiate a new engine:


NVelocity.App.VelocityEngine engine = new NVelocity.App.VelocityEngine();

//set log class type
engine.SetProperty(NVelocity.Runtime.RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, typeof(TemplateEngineLog));

//switch to local context, this way each macro/recursive execution uses its own variables.
engine.SetProperty(NVelocity.Runtime.RuntimeConstants.VM_CONTEXT_LOCALSCOPE, "true");

//allows #set to accept null values in the right hand side.
engine.SetProperty(NVelocity.Runtime.RuntimeConstants.SET_NULL_ALLOWED, "true");

//set template resource loader to strings
engine.SetProperty("resource.loader", "string");
engine.SetProperty("string.resource.loader.class", "NVelocity.Runtime.Resource.Loader.StringResourceLoader");

//initialize engine.
engine.Init();


Then assign a new logger if error reporting is desired:


TemplateEngineLog log = new TemplateEngineLog();
engine.SetProperty(NVelocity.Runtime.RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, log);


Then create a context, its similar to ViewData:


//create a context
NVelocity.VelocityContext vcontext = new NVelocity.VelocityContext();

//put default values
vcontext.Put("null", null);
vcontext.Put("true", true);

//add the context values
foreach (var key in context.Keys)
    vcontext.Put(key, context[key]);


Then we have two options, either a one time execution of a template with this:


engine.Evaluate(vcontext, sw, "", template)


or multiple executions - meaning, the template will be compiled  so it will execute a lot faster:


//gets the string resource repository
var repo = NVelocity.Runtime.Resource.Loader.StringResourceLoader.GetRepository();
Guid guidcode = Guid.NewGuid();

//puts a new template inside it
repo.PutStringResource(guidcode.ToString(), template);

nvtemplate = engine.GetTemplate(guidcode.ToString(), "UTF-8");


and for the execution:


//merge uses a saved template
nvtemplate.Merge(vcontext, sw);


The demo project is located at:
https://github.com/drorgl/ForBlog/tree/master/NVelocityDemo
Tags: , ,

Thursday, August 2, 2012

Using Google Analytics Data in Your Applications

A few years ago I've been asked to make the analytics data available to our customers, give them the tool they need in order for them to optimize their websites for SEO, check how many of their efforts have been converted to deals, leads, etc'.

We had a few options (like piwik.org), but we already had a few years of data inside google analytics and we wanted to integrate the reports with our own software, making it a one shop stop for our customers.

After attempting to retrieve data on the fly with Google API (download), We've found out we might have more requests than we anticipated for more data and more detailed reports, we decided to import it into our database, create a bunch of indexed views to ease the pain of the database (and ourselves) and give the customers what they want.

And so, a program was born.

I'll describe the stages briefly to get your own data but I won't go in into our implementation for obvious business reasons (though by the time this article was written we stopped using analytics).

First, a few notes about Google Analytics API limits, 50,000 requests per project per day, 10 queries per second per IP, 10,000 requests per profile per day, 10 concurrent requests per profile.

Sound pretty high no?

But imagine the 11th person going into your reporting page getting an error, or imagine your 10,000 users got into your reporting page and someone wants the 10,001 request. From my experience, SEO people will refresh the page as soon as they can to see if anything changed in the last 3 seconds.

Of-curse we can cache the results for X amount of time, but why not store the entire database on our servers and serve it from there? 

So how do I get my program to respect google's limits?
1. For each request, retrieve the most amount of data possible by the API, it will make each request slower, but it also save me requests, making those 10,000 per profile count more.
2. Write a method that will check if I reached the 10 concurrent requests per IP and delay the next request until one of them is finished.
3. Further extent section 2 to include a check if in the past second I requested less than 10 requests, if I'm in the limit, wait a second.

If you're not implementing a multithreaded application, the 10 per second and 10 concurrent per IP are irrelevant to you.

So lets start with a limiter, I've implemented a a class which does the limiting job, its a combination of semaphore and temporal semaphore.

Limiter.cs

Then I've added the main program, first it uses AnalyticsService and set authorization (GDataCredentials).

Then we retrieve all the profiles/accounts with AccountQuery.

Then we determine the timezone that profile is using, its important if your application is serving multiple timezones so everyone will get a consistent time. Analytics stores and serves all dates and hours in the profile's timezone, I'm using PublicDomain to process TzTimeZone as its not part of the .NET framework.

After that, we're going to retrieve the records with DataQuery. Analytics uses a combination of Metrics and Dimensions to store data. Think of Dimensions as the "group by" section in a sql query and the Metrics as the select section.

You can find the reference here: https://developers.google.com/analytics/devguides/reporting/core/dimsmets

And there's a cool tool called Google Analytics Query Explorer in which you can execute queries and see the data returned immediately.

A few more thoughts which might help you implement your own tools:
1. implementation of a timeout method execution, I've noticed that from time to time some of the methods tend to freeze.
2. a retry method execution.
3. sort of sync, you should read every day the data from yesterday until today so everything will be in sync due to time zones differences.

You can find the demo project here:
https://github.com/drorgl/ForBlog/tree/master/GoogleAnalyticsData/GoogleAnalyticsDemo


Tags: , , ,

Thursday, May 24, 2012

Dictionary vs ConcurrentDictionary

Who hasn't seen in almost every best practices guide "cache everything!", but what they forget to tell you is that by that time, the caching you're using is one of the biggest bottlenecks of your program, you try to use as many dictionaries as you can (at least for a particular caching need) and avoid locking and blocking in any way possible.


When Microsoft decided its time for .NET to start using multi-threading heavily, they came out with Parallel Extensions, later on they added ConcurrentDictionary, but I've always wondered what is the price we're paying for the dictionary to work in a thread-safe environment.


I can't stress this enough, Do not use a regular Dictionary with multi-threading!
In some cases when the dictionary is updated by two (or more) threads it will corrupt its internal structures and it will throw exceptions. sometimes items will disappear, sometimes the whole dictionary will stop working.


In the past I've implemented a dictionary with lock keyword, spinlock, read/write locks and even a copying dictionary so whenever you had to make a change, it will copy itself, make the modification and replace the reference, I didn't care about losing information, I just wanted the quickest dictionary.


So how does the ConcurrentDictionary works? well, using ILSpy, we can take a look, I can't post the source code here so you'll have to do your own digging, but apparently its using Monitor.Enter for the writing portion, which is just an alternative of the lock keyword, for the reading portion it seems that its pretty close to the regular Dictionary.


I remembered reading about lock-free hashmaps (PDF) in the past but didn't have the time looking up the algorithm, understanding it and implementing it, luckily someone already did but I can't find the original C# implementation, here's what I've found now https://github.com/hackcraft/Ariadne.




I did some benchmarks and the results are pretty interesting.
The categories (X) are the number of concurrent threads attempting to write and read.
Note: the graphs do not work in IE for now.


You may find the benchmark project at:
https://github.com/drorgl/ForBlog/tree/master/DictionaryBenchmarks


I've taken the readwrite locked dictionary from Lorenz Cuno Klopfenstein, I've implemented a minimal spinlock dictionary just for the test, don't use it.


The ThreadSafeDictionary is the star of this benchmarks, it performs exceptionally well, so if your program relies heavily on dictionaries and threading, use it.

Tags: , , , , ,

Friday, April 27, 2012

Microsoft DNS Web Admin

Most if not all DNS servers have a web interface, why not Microsoft's DNS?


I decided to write one, just because I got tired from logging in to a server every time I wanted to change something, yes, I know about remote management, it wasn't an option for that particular case. time passed by and by the time I was almost done, the project was irrelevant, I did have some fun writing it though!


So here it is before you, mostly working, some parts don't, mostly tested. 


https://github.com/drorgl/MSDNSWebAdmin


If you'd like to finish it, enjoy, its on github just for that.






Project contains two interesting libraries:


Heijden.DNS - for querying everything a DNS can tell you, including a trace.


DNSManagement - C# wrapper for WMI MicrosoftDNS namespace.

Tags: , , , , ,

Monday, May 16, 2011

Using Razor Templates In Your Application

We needed a templating engine that will work in a medium trust environment, after reviewing StringTemplate and NVelocity and we came to the conclusion that Razor can do all we need and more, plus it comes with the framework so no need for external dependencies.

You should be aware that Razor is compiling .NET code, it can and will create security breeches in your application if you allow users to change the templates, you can alleviate some of these security issues by segregating your code and giving the razor section access only to the parts it needs, think this through.

The project contains a few important parts.
1. It should have its own TemplatesController, its just an empty controller for the engine to run against.
2. Templates views directory, this is where we're storing the templates for the engine to execute.
3. Templates.cs is where some of the magic happens.
4. For the sake of the demo, I've added a custom WebViewPage called RazorBaseWebViewPage and a SimpleModel.


Templates.cs contains the following:
1. Execute - executes a view against a controller, with ViewData and Model.


/// <summary>
/// Generates a controller and context, hands them off to be rendered by the view engine and 
/// returns the result string
/// </summary>
/// <param name="viewName">Template Name</param>
/// <param name="model">Model for the view</param>
/// <param name="viewData">ViewData</param>
/// <returns>rendered string</returns>
private static string Execute(string viewName, ViewDataDictionary viewData, object model)
{
    var controller = new TemplatesController();
    controller.ControllerContext = new ControllerContext();
    controller.ControllerContext.HttpContext = new HttpContextWrapper(HttpContext.Current);
    controller.RouteData.DataTokens.Add("controller", "Templates");
    controller.RouteData.Values.Add("controller", "Templates");
    controller.ViewData = viewData;
    return RenderView(controller, viewName, model);
}


2. GetViewName - gets or writes a new template to the templates directory, it uses a hash of the template for the first part of the filename. Same trick as a hash table.


/// <summary>
/// Retrieves the view name by template and model
/// </summary>
private static string GetViewName(string template,Type modelType)
{
    //gets the razor template from a text template
    var razortemplate = GetViewContentFromTemplate(template, modelType);

    //gets the hash string from the razor template
    string hashstring = BitConverter.ToString(BitConverter.GetBytes(razortemplate.GetHashCode()));

    //check if view exists in folder
    var files = Directory.GetFiles(ViewDirectory, hashstring + "*.cshtml");
    foreach (var file in files)
    {
        if (File.ReadAllText(file, Encoding.UTF8) == razortemplate)
            return Path.GetFileNameWithoutExtension(file);
    }

    //if not, add it
    string filename = Path.Combine(ViewDirectory, hashstring + "_" + Guid.NewGuid().ToString() + ".cshtml");
    File.WriteAllText(filename, razortemplate,Encoding.UTF8);

    return Path.GetFileNameWithoutExtension(filename);
}


3. RenderView - calls the razor engine's Render. executed from Execute. (Origin)


/// <summary>
/// Renders a PartialView to String
/// </summary>
private static string RenderView(Controller controller, string viewName, object model)
{
    //origin http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/
    if (string.IsNullOrEmpty(viewName))
    {
        return string.Empty;
    }

    controller.ViewData.Model = model;
    try
    {
        StringBuilder sb = new StringBuilder();
        using (StringWriter sw = new StringWriter(sb))
        {
            IView viewResult = GetPartialView(controller, viewName);
            ViewContext viewContext = new ViewContext(controller.ControllerContext, viewResult, controller.ViewData, controller.TempData, sw);
            viewResult.Render(viewContext, sw);
        }
        return sb.ToString();

    }
    catch (Exception ex)
    {
        return ex.ToString();
    }
}


4. Render - the exposed method to do the actual rendering.


/// <summary>
/// Renders a template with parameters to string
/// </summary>
/// <param name="template">template text to render</param>
/// <param name="model">the model to give the template</param>
/// <param name="parameters">the ViewData for the execution</param>
/// <returns>rendered template</returns>
public static string Render(string template, object model, ViewDataDictionary parameters)
{
    //if empty
    if (string.IsNullOrEmpty(template))
        return string.Empty;

    //if doesn't contain razor code
    if (template.IndexOf("@") == -1)
        return template;

    //get View filename
    string fileName = GetViewName(template, (model != null) ? model.GetType() : typeof(object));

    //Execute template
    return Execute(fileName, parameters, model);
}



I've ran some analysis on the code's performance, a few places might be helpful to optimize is the GetPartialView and GetViewName are slow.

You can find the project here:
https://github.com/drorgl/ForBlog/tree/master/RazorTemplateDemo
Tags: , ,