Tasks with Timeouts

So the task is to timeout a task. now, I never thought it would take me as long as it did. Turns out it is a really tricky problem problem. I was expecting something within the framework to make life easier, there isn’t anything by default but msdn to the rescue Tasks With Timeout.

So, the extension method is

    public static class TaskWithTimeout
    {
        internal struct VoidTypeStruct
        { }
        internal static void MarshalTaskResults<TResult>(Task source, TaskCompletionSource<TResult> proxy)
        {
            switch (source.Status)
            {
                case TaskStatus.Faulted:
                    proxy.TrySetException(source.Exception);
                    break;
                case TaskStatus.Canceled:
                    proxy.TrySetCanceled();
                    break;
                case TaskStatus.RanToCompletion:
                    Task<TResult> castedSource = source as Task<TResult>;
                    proxy.TrySetResult(
                        castedSource == null ? default(TResult) : // source is a Task
                            castedSource.Result); // source is a Task<TResult>
                    break;
            }
        }
        
        public static Task TimeoutAfter(this Task task, int millisecondsTimeout)
        {
            // Short-circuit #1: infinite timeout or task already completed
            if (task.IsCompleted || (millisecondsTimeout == Timeout.Infinite))
            {
                // Either the task has already completed or timeout will never occur.
                // No proxy necessary.
                return task;
            }

            // tcs.Task will be returned as a proxy to the caller
            TaskCompletionSource<VoidTypeStruct> tcs = new TaskCompletionSource<VoidTypeStruct>();

            // Short-circuit #2: zero timeout
            if (millisecondsTimeout == 0)
            {
                // We've already timed out.
                tcs.SetException(new TimeoutException());
                return tcs.Task;
            }

            // Set up a timer to complete after the specified timeout period
            Timer timer = new Timer(state =>
            {
                // Recover your state information
                var myTcs = (TaskCompletionSource<VoidTypeStruct>)state;
                // Fault our proxy with a TimeoutException
                myTcs.TrySetException(new TimeoutException());
            }, tcs, millisecondsTimeout, Timeout.Infinite);

            // Wire up the logic for what happens when source task completes
            task.ContinueWith(antecedent =>
                                {
                                    timer.Dispose(); // Cancel the timer
                                    MarshalTaskResults(antecedent, tcs); // Marshal results to proxy
                                },
                                CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);

            return tcs.Task;
        }

        public static Task<TResult> TimeoutAfter<TResult>(this Task<TResult> task, int millisecondsTimeout)
        {
            // Short-circuit #1: infinite timeout or task already completed
            if (task.IsCompleted || (millisecondsTimeout == Timeout.Infinite))
            {
                // Either the task has already completed or timeout will never occur.
                // No proxy necessary.
                return task;
            }

            // tcs.Task will be returned as a proxy to the caller
            TaskCompletionSource<TResult> tcs = new TaskCompletionSource<TResult>();

            // Short-circuit #2: zero timeout
            if (millisecondsTimeout == 0)
            {
                // We've already timed out.
                tcs.SetException(new TimeoutException());
                return tcs.Task;
            }

            // Set up a timer to complete after the specified timeout period
            Timer timer = new Timer(state =>
                                    {
                                        // Recover your state information
                                        var myTcs = (TaskCompletionSource<TResult>)state;
                                        // Fault our proxy with a TimeoutException
                                        myTcs.TrySetException(new TimeoutException());
                                    }, tcs, millisecondsTimeout, Timeout.Infinite);

            // Wire up the logic for what happens when source task completes
            task.ContinueWith(antecedent =>
                                {
                                    timer.Dispose(); // Cancel the timer
                                    MarshalTaskResults(antecedent, tcs); // Marshal results to proxy
                                }, 
                                CancellationToken.None, TaskContinuationOptions.ExecuteSynchronously,TaskScheduler.Default);

            return tcs.Task;
        }
    }

A lot of code for doing this, and the msdn article remains the better source of explanation.

Now using this.

public class Program
	{
		private static List<int> Output = new List<int>();
		private static Random _random = new Random();
		
		public static int LongRunningTask(string message)
		{
			Console.WriteLine(message);
			Console.WriteLine("Managed thread Id " + Thread.CurrentThread.ManagedThreadId);
			//Simulate a long running task
            Thread.Sleep(TimeSpan.FromSeconds(2));
			var number = _random.Next();
			Console.WriteLine("Adding " + number + " From thread  - " + Thread.CurrentThread.ManagedThreadId);
			return number;
		}

		public static void Main(string[] args)
		{
			Console.WriteLine("In Main");
			Console.WriteLine("Managed thread Id " + Thread.CurrentThread.ManagedThreadId);
			var cts = new CancellationTokenSource();
			var tasks = new List<Task>();
			try
			{
//In the continuation check for the condition of fault (or something more if you so need) and perform the //continuation
				var t1 = Task.Factory.StartNew(_ =>	LongRunningTask("Entering task1"),
												    TaskCreationOptions.AttachedToParent)
                                     .TimeoutAfter(1000)
                                     .ContinueWith(antecedent => {
						if(!(antecedent.IsCanceled || antecedent.IsFaulted))
                                                         Output.Add(antecedent.Result);
								}
								, cts.Token);
				var t2 = Task.Factory.StartNew(_ => LongRunningTask("Entering task2"),
													TaskCreationOptions.AttachedToParent)
                                     .ContinueWith(_ => Output.Add(_.Result));
                var t3 = Task.Factory.StartNew(_ => LongRunningTask("Entering task3"), 
													TaskCreationOptions.AttachedToParent)
                                     .ContinueWith(_ => Output.Add(_.Result));
            
                tasks.Add(t1);
                tasks.Add(t2);
                tasks.Add(t3);
                            
                Task.WaitAll(tasks.ToArray());
            }
            catch (Exception ex)
            {                
                Console.WriteLine("There was an exception");
                Console.WriteLine(ex.InnerException.Message);               
            }

            Console.WriteLine("Output :");
            Output.ForEach(_ => Console.WriteLine(_));

            Console.ReadLine();
        }
    }

The important part being that the continuation is applied after the timeout and it won’t work with the other way around.
The output therefore basically looks like this :

In Main
Managed thread Id 9
Entering task1
Managed thread Id 10
Entering task2
Managed thread Id 11
Entering task3
Managed thread Id 14
Adding 194443354 From thread  - 10
Adding 792426557 From thread  - 11
Adding 230130793 From thread  - 14
Output :
792426557
230130793

Next, time I will try and write about some other things on Flirting with Tasks.

Entity Framework – Table Per Type – Gotcha

Entity Framework Table Per Type (TPT) implementation has a little gotcha ( little is really relative ). When we create table per type we will have orphan rows if the parent gets deleted and there will be orphan rows in the parent if the child gets deleted. This causes a funny picture to emerge with very bad consequences.

Gotcha

Sad Panda

Now, to get around this my simple workaround was to alter the relationships in my seed method.

context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Match] DROP CONSTRAINT [FK_ParikshaDev.Match_ParikshaDev.Questions_QuestionId]" );
context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Match] ADD CONSTRAINT [FK_ParikshaDev.Match_ParikshaDev.Questions_QuestionId] FOREIGN KEY (QuestionId) REFERENCES [ParikshaDev].[Questions] (QuestionId) ON DELETE CASCADE" );

context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Brief] DROP CONSTRAINT [FK_ParikshaDev.Brief_ParikshaDev.Questions_QuestionId]" );
context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Brief] ADD CONSTRAINT [FK_ParikshaDev.Brief_ParikshaDev.Questions_QuestionId] FOREIGN KEY (QuestionId) REFERENCES [ParikshaDev].[Questions] (QuestionId) ON DELETE CASCADE" );

context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Choice] DROP CONSTRAINT [FK_ParikshaDev.Choice_ParikshaDev.Questions_QuestionId]" );
context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Choice] ADD CONSTRAINT [FK_ParikshaDev.Choice_ParikshaDev.Questions_QuestionId] FOREIGN KEY (QuestionId) REFERENCES [ParikshaDev].[Questions] (QuestionId) ON DELETE CASCADE" );

context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Custom] DROP CONSTRAINT [FK_ParikshaDev.Custom_ParikshaDev.Questions_QuestionId]" );
context.Database.ExecuteSqlCommand( @"ALTER TABLE [ParikshaDev].[Custom] ADD CONSTRAINT [FK_ParikshaDev.Custom_ParikshaDev.Questions_QuestionId] FOREIGN KEY (QuestionId) REFERENCES [ParikshaDev].[Questions] (QuestionId) ON DELETE CASCADE" );

Fix!

Better Panda

There are things that can be better in this code. We can have the Schema name and the Table name statically typed with the help of the context. The relationship name was arrived at by making an educated guess about the relationships and then confirming them by having a look at the db that was generated previously.
I would consider this as a bug in EF. I didn’t see any way to configure this behaviour with the fluent api. I expected this to be clearly stated in the documentation or a flag or a switch be made available in the api for configuration.

Entity Framework 6 – Migrations

Migrations are needed in our day to day work and EF migrations story has become a lot better over the last year. When your database changes rapidly then migrations are needed to keep pace. Ofcourse this is nothing new, but it wasn’t available in EF before.

Enable Migrations

To enable the migrations go to Tools -> Library Package Manager -> Package Manager Console.
Type Enable-Migrations in the console.
-Force parameter is optionally available if you want to overwrite an existing migrations.

Creating a migration

Once the migrations are enabled, use the Add-Migrations command to add a migration. Give a logical name to the migration, attach a issue number if needed to the migration name like myawesomemigration-issue#1234. It really helps when you want to go up and down the migrations. When you choose to enable migrations, do it in the correct project if you have multiple projects in the solution.
Once the migration has been added, then you will see two new files within a new folder Migrations pop in. One of these is the migrations file which will have your nice name and the other one is Configuration.cs which will have your configuration. Your awesome migrations file will have all your create table syntax, this seems to be a DSL. You can do your funny bits here, add an Index tweak mania can begin here. Do read the file carefully though for the first few times. It should not be too dense and it should all make sense. If something looks off highly likely that your configuration in the model is fishy. It has two methods which allow you to move up and down between the migrations.

Configuration.cs is a useful class. It has the seed method with which you can seed you database. You can seed your db with test data which you will need for running the system tests (which you should with EF).

Updating your database

All said and done, time to update our database to the latest version. In the package manager console, write
Update-Database -Verbose. The verbose flag gives you back the sql as well for you to see. Options are available to script it out to a file as well if you want to hand it over to someone else.

As of this writing EF 6 beta has broken this bit bug
You should be safe on previous bits ( till alpha or EF 5 and below ).

Have a look at your database when the command finishes, your database should be updated.

Irritant

Next, I will write about a gotcha that made me think long and hard if I was very dumb.

Team City – Recover Admin Password

The trials and tribulations of this world are beyond me. Sometimes, a simple gesture can save your life.
I lost(forgot, forgive my small brain it has to keep up with a day job) my TeamCity login details.
Searching online will lead you to this place Forgot Team City Password.

The solution there is mighty correct barring two things. One, your TeamCity data directory path is likely to C:\ProgramData\JetBrains\TeamCity\ on a windows box and not C:\users\foo\TeamCity. Second, you need to run CMD as admin.
So,


Step 1 Stop TeamCity service ( either through services.msc or the bat files ).

Step 2  Open CMD as ADMINISTRATOR
(don't forget the admin part you will go bonkers trying to figure out what is happening)
and go to C:\TeamCity\webapps\ROOT\WEB-INF\lib

Step 3 type -cp server.jar; hsqldb.jar ChangePassword USERNAME PASSWORD C:\ProgramData\JetBrain\TeamCity

If all is successful then you password has been reset and you can login. Here’s hoping to a few hours saved for anyone who comes around to reading this.