Showing posts with label Advanced Programming. Show all posts
Showing posts with label Advanced Programming. Show all posts

Tuesday, April 12, 2016

Advanced Programming: An easy way to manage critical zones by locking


So, sometimes people might ask what is the critical zone, or why shall we manage it?
Well, on multi-thread apps like web applications, it is possible that a thread leaves a method and go to sleep and another thread change something that has an impact on those values.
The simplest example that I can come up is an "IncreaseAndSave" method like this:

Code:
void IncreaseAndSave()
{
     var value= ReadValueFromDB();
     Value++;
     // The thread1 goes to sleep
      SaveValueInDB(Value);
}

Simple scenario:
Lets say we have a value "10" in our DB and 2 threads that call our method almost at the same time. The first one will try to run the code, it reads the value from DB and increase it so Value will be "11" in our memory. Then the thread will go to sleep and thread2 will run the process. It will read value "10" again from DB since T1 didn't save it and will increase it to "11". Now both threads will call save method and we will end up with "11" instead of "12".
So the zone that we call a critical zone is from reading to saving Data in the DB.


Simplest Solution
Well there is a reserved word in C# (and almost all other programming languages) for lock. The functionality is very simple. it is like a safe box. When you lock it, no one else can enter or lock it until you leave the safe box and then someone else can take over.
The only important note is that you have to lock the same object :D (safe box)
Code:
void IncreaseAndSave()
{
     lock(_object)
     {
      var value= ReadValueFromDB();
      Value++;
      // The thread1 goes to sleep
       SaveValueInDB(Value);
      }
}

Make it a bit more complex
So, we saw the problem when 2 threads want to access a critical section in a method but what if our critical zone is inside 2 different methods?
For instance, if we have a decrease method, one thread may decrease the value in DB while the other one still didn't save its value.
Of course the solution is to lock both stuff with the single object (the same safe-box)

Make even more Complex
We saw the code for locking some part of codes, but the drawback of that code is that the lock area cannot be accessed by multiple threads even though they might not have an impact on each other.

For instance, take updated function below as an example. The thread thr1 will try to increase the value for key =1 so it will lock the process and goes to sleep, then thr2 will try to increase the value for key=2 but since the area is already locked by thr2, it has to wait.
It is pretty clear that in a simple web application, there will be a long queue for just saving stuff and etc, and it will be slow like if it is running on a computer with only 1 CPU and 1 thread.
So what can we do to make it efficient?

Code:
void IncreaseAndSave(int key)
{
  lock(object)
     {
       var value= ReadValueForKeyFromDB(key);
       Value++;
       // The thread1 goes to sleep
       SaveValueInDB(key,Value);
      }
}


Solution
We need a class to return the lock for each key. The idea is to have a bank of  safe boxes instead of only 1. But we have to pay attention that the bank is the one who is responsible for finding the mutual interest. In the other word, on runtime the thread will ask the LockContainer(banker) about the safe-box with special key and then it will try to lock the safe-box (lock).
It can simply be done by code below:

Code:
  public class LockContainer
    {
        private BlockingCollection<object> lockItems { get; set; }

        private object LocalLockItem { get; set; }


        public LockContainer()
        {
            lockItems = new BlockingCollection<object>();
            LocalLockItem = new object();
        }

        public object GetLockItem(string str)
        {
            lock (LocalLockItem)
            {
                if (!lockItems.Any(li => (string)li == str))
                {
                    lockItems.Add(str);
                }
                return lockItems.First(li => (string)li == str);
            }
        }
    }

* Implementing the process required a list, but at the same time, adding items to list and reading them would make another critical zone, but fortunately, .net has a thread safe list called BlockingCollection which you can use with multiple threads.

How to use the code
You will need to create the container somewhere. If your critical zone is only inside a class, use it as a property of that class and make it static.
If you need to lock different areas in different classes for a key, implement a singleton design pattern (which can be found in here) and return the lock container. Then you can use it easily:
Code:
  LockContainer locks = new LockContainer();
-------------------

void IncreaseAndSave(int key)
{
  lock(locks.GetLockItem(key))
     {
       var value= ReadValueForKeyFromDB(key);
       Value++;
       // The thread1 goes to sleep
       SaveValueInDB(key,Value);
      }
}

  



Friday, April 8, 2016

Using Exceptions, good or bad?!

Last year when I started to discuss this matter with my friends, I was almost sure that they all love exceptions, but I've found out that I was wrong! So lets could be the drawback of the exceptions and shall we use them or not.


First, lets say an exception is like a sword. You can use it when something happens to protect your code from unwanted results, but at the same time cut you if someone throws it and no one catch it.
Also, no one will use a sword to peel an apple! will you?! :D


Advantages
Well, I myself cannot imagine how hard it would be to write a clean code without exceptions. :) You will prevent unwanted effects with only one line of code. There is no need to return message, value, etc. it could be logged very easily and your log can contain every detail that you may need. specially the call stack! By using typed exceptions (who won't?!) you can choose different reactions and by using inheritance, you can have even more control.

Disadvantages
handling lots of exceptions is hard. You have to have a good idea about what is going on in your project. As I said, it is a sword, if you use it in a small code, like throwing an exception and handling it inside a class (or even worst - inside a method :| )
If you don't know what you are doing, you will most probably end up with a very ugly code that will be very hard to maintain

Where to throw an exception

An exception has to be thrown in these cases:
1- When there is a special situation in your code.
Think of normal scenarios that you've seen until now, like when memory is not accessible, network is down or etc. These situations have a meaning in their criteria, but at the same time they will tell make the user (code) to handle them properly.It is important to notice that it is not only connected to a low level code, when your code is about bank accounts you can have exceptions like "the balance cannot be negative" or "insufficient funds", etc. or for a method that handles shipment it can be "Product already shipped" or "The stock is empty", etc.

2- Where your domain ends as a wrapper
Basically speaking, you may need to have lots of different events in your code, but in many cases you don't want to return the complete details to the one who consumes your methods/services/package. For instance, you may have different rules in a banking system that you need to manage internally, but when there is a relation to other system, it just needs to know that an exception from "Specific Type" happened, and maybe a message and a code for the reference, there is no need for additional data.

Where to handle Exceptions
Well this one is obvious when you know the first part,
Of course on any outer edge of your domain/service you can decide if you want to take an action on your specific exceptions. If you have created an exception to stop the whole system, then you have to let it go, otherwise you have to handle the exception and take a suitable action.
A long sword can only handled by a strong man while even a girl can handle a short and light sword.

Also, if you are interacting with a human, you have to make sure that no exception reaches him. You just need some messages as a hint/error for the customer, and nothing more.



Tuesday, March 8, 2016

A simple queue for EpiServer

Intro
Queuing is one of the base procedures that you may need as a software developer specially if you are working on web.Think as a task that you want to make sure that it will be done, but you don’t want to suspend your current process for it. for instance you want to send an email in a part of a method or task. you don’t want to wait for email response and you want to try sending it for many times, but you never want your methods to wait for it.
If you are developing on EpiServer, you probably know that there is a dynamic data type which is pretty good for implementing a queue.

Cecilia von Wachenfeldt has a post in here where she describes a simple solution for that. However, I don't like to have both queue and queue item on the same class. From the software architectural view, we have to have a queue class that handles primitive queuing functions (adding to queue, finding unprocessed items, Processing items and deleting them). Then for each type queue, we can just create a corresponding queue-able Item and ask use our queue to handle the object :)

Theory

There has to be a queue, with queue functions. There has to be an enum for the status of the item. Then the queue has to handle everything using each items methods.

This is the list of classes that we need:

1- Queue
2- An interface for Queueable Items (IQueueable)
This interface contains properties that the queue will use like ErrorCount, LastError, Status, etc. and basic methods for processing each special type Like Process().
3- Queueable item which inherits from our IQueueable
This item is simply the object that we want to save into DB. It contains our queue properties/methods and also the required data that you need to use, in order to proceed.

Implementation
Lets say that we want to implement an email queue system, so if the network was down or etc, we won't loose any emails. Our queue and IQueueable are of course the same but for the Queueble Item we have something like this:
First, we have to implement our enum to decide if the item is
Code:
public enum QueueItemState
{
Queued = 0,
Processed = 1,
Retrying = 2,
Failed = 3
}
Then we have to write our Interface:
public interface IQueueableItem
{
int ErrorCount { get; set; }
string LastError { get; set; }
DateTime? QueuedTime { get; set; }
DateTime? CompeletedTime { get; set; }
EnumsQueueItemState State { get; set; }
void AddError(string errorMessage);
bool Process();
Identity Save();
void SetToFaild(string errorMessage);
}

Then we have to implement our interface and add our additional functionality/properties:
(Pay attention to EPiServerDataStore property that cause Episerver to save this item into DynamicData )
Code:
[EPiServerDataStore(AutomaticallyRemapStore = true, AutomaticallyCreateStore = true)]
public class QueueableEmailItem : IDynamicData, IQueueableItem
{
.... [IQueueableItem properties]
public string EmailSubject { get; set; }
public string EmailBody { get; set; }
public string EmailTo { get; set; }
public int? EMailPriority { get; set; }
public bool Process()
{
var priority = EMailPriority.HasValue ? (MailPriority)EMailPriority.Value : System.Net.Mail.MailPriority.Normal;
MailService.Service.Send(EmailSubject, EmailBody, EmailTo, priority, attachedItems);
return true;
}
}

We will need a QueueBase class that handles your queue items. The queue will try to read and execute data that implement IQueueableItem. 
There is only one problem, which is reading items from DB with generics, So I just do the process in the queue base and do the other stuff in the inherited classes using polymorphism.
Code:
public abstract class QueueBase where T : IDynamicData, IQueueableItem
{
public void Proceed()
{
var queue = GetQueuedItems();
if (!queue.Any())
return ;
foreach (var item in queue)
{
try
{
// Exit if the error count is greater or equal to the retry count
if (item.ErrorCount >= RetryCount)
{
item.SetToFaild("RetryCount limit");
continue;
}
if (item.TryProcess())
{
item.State = Enums.QueueItemState.Processed;
item.Save();
continue;
}
item.State = Enums.QueueItemState.Retrying;
item.Save();
}
catch (Exception ex)
{
if (item.State!= Enums.QueueItemState.Failed)
{
item.State = Enums.QueueItemState.Retrying;
}
item.AddError(ex.message);
item.Save();
}
}
}
}
Of course you can have a better code, add logs/ return report/ send email to admin if failed, etc. but this is the simplest code that I could come up with :)
Now we will need to inherit from this class for the emailQueue:
Code:
public class EmailQueue : QueueBase<QueueableEmailItem>
{
public Identity AddToQueue(string to, string emailSubject, string body, MailPriority mailPriority = MailPriority.Normal)
{
var item = new QueueableEmailItem
{
EmailTo = to,
EmailSubject = emailSubject,
QueuedTime = DateTime.Now,
State = Enums.QueueItemState.Queued,
ErrorList = new List<string>(),
EmailBody = body,
EMailPriority = (int)mailPriority
};
return item.Save();
}
protected override List<QueueableEmailItem> GetQueuedItems()
{
var store = typeof(QueueableEmailItem).GetStore();
var query = (
from item in store.Items<QueueableEmailItem>()
where item.State == Enums.QueueItemState.Queued || item.State == Enums.QueueItemState.Retrying
select item);
return query.ToList();
}
}