<CharlieDigital/> Programming, Politics, and uhh…pineapples

2Apr/140

What Alan Watts Can Teach Us About Leadership

Posted by Charles Chen

I was listening to a talk by Alan Watts and found one bit of advice that really connected to what I've learned about leading others.

The principle is that any time you -- as it were -- voluntarily let up control.

In other words, cease to cling to yourself; you have an excess of power because you are wasting energy all the time in self defense.

Trying to manage things, trying to force things to conform to your will.

The moment you stop doing that, that wasted energy is available.

Therefore you are in that sense -- having that energy available --  you are one with the divine principle; you have the energy.

When you are trying, however, to act as if you were god, that is to say you don't trust anybody and you are the dictator and you have to keep everybody in line you lose the divine energy because what you are simply doing is defending yourself.

One mistake that I've been guilty of is to try to force things to conform to my will on various projects (I still do it to varying degrees!).  It is usually with the best of intentions -- for a cleaner framework, a better product, a more efficient process -- but at the same time, it is true that a lot of energy is spent wasted in doing so.

What is the alternative, then?

I think Watts is right that a level of trust has to exist that the team around you can help you achieve your project goals.  Instead of expending the energy in controlling the members of the team, spend the energy in building that trust through training, mentorship, guidance, and giving up not just control, but responsibility.

Sometimes that trust will be unwarranted, but sometimes, that trust will pay itself back many-fold.

30Jan/14Off

Stateless vs. Appccelerate.StateMachine

Posted by Charles Chen

I've been investigating workflow engines lately (specifically, state machine libraries) and it's come down to Stateless vs. Appcelerate.StateMachine.

First, a digression on why I'm avoiding Windows Workflow Foundation (WF).  It's true that there's tons of documentation, support from Microsoft, perhaps lots of experienced developers, but I count myself as one among many who feel burned by our experience with WF.  I've used the first release of WF on FirstPoint and mostly ended up regretting it for the poor performance and complexity (making it hard for new developers to pick it up).  I've also used the first release on various other SharePoint projects since then on top of Nintex and, again, it's been dogged by hard to trace bugs, poor performance, and stuff that's generally cumbersome (like deployment, for instance).

Microsoft seems to have addressed a lot of these issues by totally rewriting WF in .NET 4.0, but this in and of itself raises a serious question: how stable is the framework?  Sure, Microsoft provided a migration path from legacy WFs to new WFs, but it's still a headache.  Aside from that, even just looking at the APIs, it's clear that it's extremely heavy and does nothing to alleviate the poor practices which are possible with WF.

Thus enters my search for alternatives including Amazon Simple Workflow.  In the end, I've narrowed it down to Stateless and Appccelerate.StateMachine.

To test the intuitiveness, ease of use, and performance, I wrote a simple example with both of them.  I modeled the phone example from the Stateless documentation and ran it in a loop of 1,000,000.

The loop looks like so:

internal class Program
{
    private static void Main(string[] args)
    {
        var stopwatch = new Stopwatch();

        stopwatch.Start();

        for (int i = 0; i < 1000000; i++)
        {
            var phone = new Phone();

            phone.CallDialed();
            phone.CallConnected();
            phone.PlacedOnHold();
            phone.TakenOffHold();
            phone.HungUp();
        }

        stopwatch.Stop();

        Console.Out.WriteLine(stopwatch.ElapsedMilliseconds);
    }
}

The implementation of the phone in Stateless looks like so (common parts omitted for brevity):

namespace StatelessTest
{
    public class Phone
    {
        private readonly StateMachine<State, Trigger> _phone = new StateMachine<State, Trigger>(State.OffHook);

        private readonly Stopwatch _stopwatch = new Stopwatch();

        public Phone()
        {
            _phone.Configure(State.OffHook)
                  .Permit(Trigger.CallDialed, State.Ringing);

            _phone.Configure(State.Ringing)
                  .Permit(Trigger.HungUp, State.OffHook)
                  .Permit(Trigger.CallConnected, State.Connected);

            _phone.Configure(State.Connected)
                  .OnEntry(StartCallTimer)
                  .OnExit(StopCallTimer)
                  .Permit(Trigger.LeftMessage, State.OffHook)
                  .Permit(Trigger.HungUp, State.OffHook)
                  .Permit(Trigger.PlacedOnHold, State.OnHold);

            _phone.Configure(State.OnHold)
                  .SubstateOf(State.Connected)
                  .Permit(Trigger.TakenOffHold, State.Connected)
                  .Permit(Trigger.HungUp, State.OffHook)
                  .Permit(Trigger.PhoneHurledAgainstWall, State.PhoneDestroyed);
        }

        private void StartCallTimer()
        {
            _stopwatch.Start();
        }

        private void StopCallTimer()
        {
            _stopwatch.Stop();
        }

        public void CallDialed()
        {
            _phone.Fire(Trigger.CallDialed);

            //Console.Out.WriteLine("Dialed");
        }

        public void CallConnected()
        {
            _phone.Fire(Trigger.CallConnected);

            //Console.Out.WriteLine("Connected");
        }

        public void PlacedOnHold()
        {
            _phone.Fire(Trigger.PlacedOnHold);

            //Console.Out.WriteLine("On Hold");
        }

        public void TakenOffHold()
        {
            _phone.Fire(Trigger.TakenOffHold);

            //Console.Out.WriteLine("Off Hold");
        }

        public void HungUp()
        {
            _phone.Fire(Trigger.HungUp);

            //Console.Out.WriteLine("Hung Up");
        }
    }

    // Define enums here
}

The implementation of the phone in Appccelerate.StateMachine looks like so:

namespace StateMachineTest
{
    public class Phone
    {
        private readonly PassiveStateMachine<State, Trigger> _phone = new PassiveStateMachine<State, Trigger>();

        private readonly Stopwatch _stopwatch = new Stopwatch();

        public Phone()
        {
            _phone.In(State.OffHook)
                  .On(Trigger.CallDialed).Goto(State.Ringing);

            _phone.In(State.Ringing)
                  .On(Trigger.HungUp).Goto(State.OffHook)
                  .On(Trigger.CallConnected).Goto(State.Connected);

            _phone.In(State.Connected)
                  .ExecuteOnEntry(StartCallTimer)
                  .ExecuteOnExit(StopCallTimer)
                  .On(Trigger.LeftMessage).Goto(State.OffHook)
                  .On(Trigger.HungUp).Goto(State.OffHook)
                  .On(Trigger.PlacedOnHold).Goto(State.OnHold);

            _phone.DefineHierarchyOn(State.Connected)
                  .WithHistoryType(HistoryType.None)
                  .WithInitialSubState(State.OnHold);

            _phone.In(State.OnHold)
                  .On(Trigger.TakenOffHold).Goto(State.Connected)
                  .On(Trigger.HungUp).Goto(State.OffHook)
                  .On(Trigger.PhoneHurledAgainstWall).Goto(State.PhoneDestroyed);
        }

        private void StartCallTimer()
        {
            _stopwatch.Start();
        }

        private void StopCallTimer()
        {
            _stopwatch.Stop();
        }

        public void CallDialed()
        {
            _phone.Fire(Trigger.CallDialed);

            //Console.Out.WriteLine("Dialed");
        }

        public void CallConnected()
        {
            _phone.Fire(Trigger.CallConnected);

            //Console.Out.WriteLine("Connected");
        }

        public void PlacedOnHold()
        {
            _phone.Fire(Trigger.PlacedOnHold);

            //Console.Out.WriteLine("On Hold");
        }

        public void TakenOffHold()
        {
            _phone.Fire(Trigger.TakenOffHold);

            //Console.Out.WriteLine("Off Hold");
        }

        public void HungUp()
        {
            _phone.Fire(Trigger.HungUp);

            //Console.Out.WriteLine("Hung Up");
        }
    }

    // Define enums here
}

And here are the results:

2014-01-30_095250

Here are my observations:

  1. Stateless is about 4x faster than Appccelerate.StateMachine
  2. Stateless syntax is a little bit more intuitive for creating hierarchies
  3. Appccelerate.StateMachine documentation is much more thorough and much more complete than Stateless
  4. But Stateless has more downloads (thus more users) and more presence on StackOverflow (should you need it)
  5. Appccelerate.StateMachine has some cool features around logging and extensibility, but quite honestly, I don't think they are needed given that if you use a composite pattern around your state machine, you can really manage that yourself much more concisely.
  6. The external persistence infrastructure of Stateless is simple, but not very intuitive or well documented
  7. The Appccelerate.StateMachine Nuget package did not work with the package manager console and Visual Studio 2012, requiring me to manually download and compile the source (which I don't mind, but raises some doubt)

All said and done, I think we will use Stateless as it is a very barebones and highly performant state machine, which is perfect for our needs.  Look for more Stateless posts in the future!

Attached is the sample code: StateMachineTest

Filed under: Dev, Uncategorized, WF No Comments
23Aug/11Off

Damn It, Microsoft (SharePoint)

Posted by Charles Chen

Came across an interesting quirk today with regards to AddFieldAsXml in the SharePoint API.

It turns out that SharePoint doesn't really give a damn what you want to call your field when it adds it to the list; it's going to damn well do whatever it damn well pleases!

You see, in the MSDN documentation, it implies that you can specify the display name and the internal name (just look at that sample code).

However this isn't the case and, as Bill Simser points out, this has been an issue going back to 2005.

Thankfully, as commenter Morten Bundgaard Pedersen points out, you can use the SPAddFieldOptions.AddFieldInternalNameHint option to force SharePoint to use the name value that you specify in the XML.

Seems kind of silly to me given that this is the most likely use case and should be enabled by default given that the intent -- in specifying the Name and StaticName fields would be to, you know, use them when creating the field.

Damn it, Microsoft.

26Oct/08Off

Another Day, Another Endorsement…

Posted by Charles Chen

This time, from Alaska's own Anchorage Daily News:



Sen. Barack Obama, the Democratic nominee, brings far more promise to the office. In a time of grave economic crisis, he displays thoughtful analysis, enlists wise counsel and operates with a cool, steady hand. The same cannot be said of Sen. McCain.


Sen. Obama warned regulators and the nation 19 months ago that the subprime lending crisis was a disaster in the making. Sen. McCain backed tighter rules for Fannie Mae and Freddie Mac, but didn't do much to advance that legislation. Of the two candidates, Sen. Obama better understands the mortgage meltdown's root causes and has the judgment and intelligence to shape a solution, as well as the leadership to rally the country behind it. It is easy to look at Sen. Obama and see a return to the smart, bipartisan economic policies of the last Democratic administration in Washington, which left the country with the momentum of growth and a budget surplus that President George Bush has squandered.


What's next, Obama winning Arizona?


In a separate endorsement, the Financial Times writes:



Obama is the better choice


...a campaign is a test of leadership. Mr Obama ran his superbly; Mr McCain’s has often looked a shambles. After eight years of George W. Bush, the steady competence of the Obama operation commands respect.


In responding to the economic emergency, Mr Obama has again impressed – not by advancing solutions of his own, but in displaying a calm and methodical disposition, and in seeking the best advice. Mr McCain’s hasty half-baked interventions were unnerving when they were not beside the point.


On foreign policy, where the candidates have often conspired to exaggerate their differences, this contrast in temperaments seems crucial. For all his experience, Mr McCain has seemed too much guided by an instinct for peremptory action, an exaggerated sense of certainty, and a reluctance to see shades of grey.


John Hodgman -- you may know him as "PC" from the Apple commercials -- raises some excellent points in an interview over at The A.V. Club:



JH: The thing that I find so compelling is that right now Obama's whole campaign strategy is simply [to] speak to people as though they were adults and trust that the truth of the world situation will be evident to them. For him to be attacked as a friend of a terrorist, for "palling" around with terrorists and to simply go back and say, "No, I'm not"? That was such a refreshing political moment. It's like he's saying, "Oh, you know that's not true. You know what's happening here." So much of the past eight years in politics, whether you're a Democrat or a Republican, you have to acknowledge is based on what the Bush people to themselves have described outside the reality-based community. That the words they were speaking had no basis in reality and they felt no compulsion to exist in a real world. They were creating a world of their own imagining.


<snip/>


Do I think that his candidacy is historic? Sure, that's exciting too, but what I think it's really amazing that he exists in the same world that I also inhabit and no other political candidate lives in that world right now. They live in a made-up world that is not reality. I think that that's why you see Obama surging right now. It's that the people like the fact that Obama lives in the world that they live in.


I think the keyword is "reality".  Hodgman hits it on the head with regards to why Bush has failed and why McCain has also failed to deliver (so far) in this campaign.  Neither man seems to be comfortable embracing reality.


An excellent interview that's worth a read.


Also, two of my favorite images from this election:




Check out the official flickr photostream for more good stuff.

Filed under: Uncategorized No Comments
27Mar/07Off

SharePoint “Feature”: Pain In The Ass…

Posted by Charles Chen

Just to share some findings on working with SharePoint features:



  • The Elements.xml file that you include with your feature deployment cannot contain XML comments; if it does, you will encounter an error when you try to activate your feature using STSADM.exe.  Why?  Who knows.

  • The <type/> element in the Elements.xml file, according to the schema documentation, can only occur once.  This seems to imply that you will need a different Elements.xml file to subscribe to each event type that you want to handle.

  • And of course, Microsoft does not include the list of valid values (and if they do, it's not easy to find in the documentation).  Instead, I pulled the values using Reflector from the SPEventReceiverType enumeration.

The following is the enumeration listing:

public enum SPEventReceiverType {
ContextEvent = 0x7ffe,
EmailReceived = 0x4e20,
FieldAdded = 0x2775,
FieldAdding = 0x65,
FieldDeleted = 0x2777,
FieldDeleting = 0x67,
FieldUpdated = 0x2776,
FieldUpdating = 0x66,
InvalidReceiver = -1,
ItemAdded = 0x2711,
ItemAdding = 1,
ItemAttachmentAdded = 0x2717,
ItemAttachmentAdding = 7,
ItemAttachmentDeleted = 0x2718,
ItemAttachmentDeleting = 8,
ItemCheckedIn = 0x2714,
ItemCheckedOut = 0x2715,
ItemCheckingIn = 4,
ItemCheckingOut = 5,
ItemDeleted = 0x2713,
ItemDeleting = 3,
ItemFileConverted = 0x271a,
ItemFileMoved = 0x2719,
ItemFileMoving = 9,
ItemUncheckedOut = 0x2716,
ItemUncheckingOut = 6,
ItemUpdated = 0x2712,
ItemUpdating = 2,
SiteDeleted = 0x27d9,
SiteDeleting = 0xc9,
WebDeleted = 0x27da,
WebDeleting = 0xca,
WebMoved = 0x27db,
WebMoving = 0xcb
}

Of course, these values are in hexadecimal and for some reason, the <type/> element insists on the integer values.  So just be sure to convert the value to integer (try using Google for that).

Filed under: Uncategorized No Comments
27Mar/07Off

Wait, what?

Posted by Charles Chen

So CNN has a video on the mythical Japanese Gyroball.


After watching this, I'm more curious about their dubious use of information from the Net.  From YouTube, specifically.  Uh, when did random people commenting on YouTube video logs count as newsworthy sources?  And when CNN pulls something like this, do they have to contact that commenter for permission to use the comment?


But in any case, speaking of the gyroball, for anyone interested, there is a great little (skit?) article over at ESPN by Patrick Hruby.

Filed under: Uncategorized No Comments