Monday, December 26, 2011

C#: Timer, Deferred Evaluation & GC

Following is the snippet of benign (at least by appearance) code that had been cause one of the bugs we faced recently.

The class schedules the given jobs on a timer. The start time for the jobs is around 10 hours from the point the scheduler Start is executed. The timer fires every 24 hrs periodically.

As unexpected, the timer never fired, not even once in production.

We did not face any issue related to this code in development environment, the only difference was that the delay time and period for the timer were shorter in the unit test.

Key suspect in such code behavior is GC. GC has high probability of execution in a long running process than a short running unit test.

The issue was indeed GC, the timer was being garbage collected hence the timer callback was not being executed.

Here is the detailed analysis of the code.
  •  The Loc 1 in the code is a Select expression which is implemented  by deferred execution.
  •  The Loc 2 in the code exists to ensure the Select is executed and timer is created/scheduled.
  •  The key issue with the code is no reference to the Timer object created is retained.  Hence, the Timer object is garbage collected.
  • Even though the Loc 1 seems to indicate that the reference to the Timer is assigned to the _timers field, it's not so. The _timers field holds the reference to the Select iterator. In other words, the lambda code itself.
GetType() on _timers will return System.Linq.Enumerable+WhereSelectListIterator`2 [System.Threading.TimerCallback,System.Threading.Timer]
  • If the timer is garbage collected, what is the observed behavior in the Dispose method of the JobScheduler ? 
The foreach loop actually creates new timers as a result of Select execution again and disposes them. 
So the current situation with the code is
  • Timer will not be fired if the GC runs.
  • Timer created will never be stopped by Dispose if the GC does not collect it.
The solution is to convert the output of the Select iterator using toList()or an equivalent method . This method not only forces eager evaluation but also creates a proper enumerable list of Timer objects - System.Collections.Generic.List`1[System.Threading.Timer]
This is the Gist of the the complete program to observe the issue/code behavior.


Sunday, December 11, 2011

Prolog: List Difference

Today I was implementing a Prolog program to find the difference between two lists.

Here is the problem statement and the expected output.

minus([1,2,3,4],[1,3],W).
W=[2,4]
yes

As a beginner in Prolog, I tend use the accumulator based approach to find the solution. Here is what I came up with spending some significant time at the Prolog interpreter and debugger.


minusAcc(L,[],_,L) :- !.
minusAcc([],_,A,A) :- !.
minusAcc([H|T],SL,A,W) :- \+memberchk(H,SL),!,
                            append([H],A,AL),
                            minusAcc(T,SL,AL,W).
minusAcc([_|T],SL,A,W) :- minusAcc(T,SL,A,W).
minus(L,SL,W) :- minusAcc(L,SL,[],W).

This program gives the expected output but does not preserve the order. It actually gives the output in the reverse order because of the inherent recursion in the program.  Following is output generated by this program.

minus([1,2,3,4],[1,3],W).
W=[4,2]
yes

Since, I wrote this routine for use in list sorting, the order did not matter and I decided to live with this program.

Meanwhile, I had a look at the implementation available on the web for the same purpose and I found the following program on stackoverflow very interesting.

minus(L,[],L) :- !.
minus([],_,[]) :- !.
minus([H|T],SL,W) :- memberchk(H,SL),!,minus(T,SL,W).
minus([H|T1],SL,[H|T2]) :- minus(T1,SL,T2).

This program gives the expected output and preserves the order too. This program also uses the classic accumulator (unlike mine) based approach, but here the result itself is the accumulator. I had to trace it on debugger for about 10 mins (this is my 2nd day on prolog) to understand the control flow. It was totally worth it!

Gem of a program! Made my weekend!

BTW, here is the gist of my Day 2 of Prolog using Seven Languages in Seven Weeks!


Sunday, November 13, 2011

Installing Io on Snow Leopard

Started on Seven Languages in Seven Weeks . Interesting set of 7 languages. Y'day reached Io - Day One. Had to do some googling around to get Io working on OS X.

In case you intend to do the same, here is the gist of the steps required to get going

  • Download Io source from git-repo
sudo git clone git://github.com/stevedekorte/io.git
  • Next step is to run the build.sh file in the cloned git  io directory. You might get the following error
~/software/io/libs/iovm/source/IoObject_inline.h:322: error: ‘always_inline’ function could not be inlined in call to ‘IoObject_rawGetSlot_’: recursive inlining

  • You need to modify the file  ~/software/io/libs/basekit/source/Common_inline.h change
#define NS_INLINE static __inline__ __attribute__((always_inline)) 
in the section #if defined(__APPLE__)  to
#define NS_INLINE static inline

        Friday, April 15, 2011

        Trying REBOL

        REBOL was the language I wanted to explore. Today I thought of writing a timezone converter application using REBOL.

        The application should be able to convert time from Indian timezone to Munich and Boston timezone. This conversion is related to my current project.

        With this weird requirement, I decided to use the most weird way to convert time. I decided to use the timeanddate.com timezone converter to do the conversion. As a result, the application has to make an HTTP GET call to this link and parse the resulting web page to find the converted time.

        Summarizing the Approach:
        1. Write a REBOL UI application that takes the Indian time as input
        2. On click of Convert, makes an HTTP call to the website with input given by the user.
        3. Parse the resulting web page and find the converted time.
        4. Show the converted time on the UI !!

        Here is the REBOL code for the application.
        This is a REBOL code for timezone convertor

        REBOL
        [
        Title: "Timezone Convertor IN to BOS & MUN"
        Author: "Srikanth Seshadri"
        ]

        t-time: to-string now/time

        time-get: func [inp-time tz] [
        page: reform [
        "http://www.timeanddate.com/worldclock/converted.html?hour="inp-time/hour"&min="inp-time/minute"&sec="inp-time/second"&p1=438&p2="tz]
        tzurl: to-url page
        tz-text: load/markup tzurl
        zone-found: false tg-time: now
        foreach item tz-text [
        if all [string? item zone-found ] [ tg-time: item break]
        if all [string? item any[ find item "(U.S.A" find item "(Germ"] ] [zone-found: true]
        ]
        tg-time
        ]

        gui: layout [
        backdrop effect [gradient 0x1 white]
        across
        h3 "Timezone Converter IN -> BOS & MUN" black return
        lab "Indian Time"
        t-time: field t-time 60x24 return
        tab
        button "Convert Time" [
        inp-time: (to-time t-time/text)
        if inp-time
        [
        boslbl/text: reform ["Time in Boston: " time-get inp-time 43]
        munlbl/text: reform ["Time in Munich: " time-get inp-time 83]
        show boslbl
        show munlbl
        ]
        ] keycode [#"^m"] return
        boslbl: h4 "[---------------------------------------------------------------------]" return
        munlbl: h4 "[---------------------------------------------------------------------]" return
        ]
        view center-face gui

        and the output

        This is most strange way to do timezone conversion, but the learnings and development was fun; all the effort was worth it!