Wednesday, 20 March 2013

A Logo for TruthVine

I’m delighted to announce that TruthVine now has a logo:

TruthVine - Share Sermons Online

We also have an icon form that we can use in social media handles (our twitter account, for example), and for application icons:

Truthvine - Concepts 2 - Mini Icon

Graphic design work was done by the talented Chris Hesketh, who is now beavering away to make our landing page look presentable.

Saturday, 9 March 2013

A crash course on the importance of cross-browser testing

Having trumpeted the successful launch of my startup’s minimal-viable-product on our first customers website yesterday, I went to bed feeling pretty satisfied with the week’s work.

I woke up this morning to find a tweet and a comment on my blog alerting me to an issue with the site. Dave kindly tweeted to say he was getting Http 404 errors when clicking links to view sermons. I checked the site again, and it “worked for me”TM so I concluded it was just a one off issue, and hoped it would go away. Then Mark commented that he was getting problems when viewing the site in Firefox. Ah!

Rob and I developed the site using Google Chrome. I also tested it on Safari on my iPad. Both worked fine, so I optimistically assumed it worked everywhere.

Prompted by Mark’s comment I downloaded Firefox, and tried the site for myself. Instead of this:

image

I saw this:

image

I quickly diagnosed the problem: Firefox wasn't loading the css file that styles the content our script injects into the site. Our script was loading the style sheet dynamically by injecting a <link/> element into the page immediately before our content. This was working fine in Chrome and Safari – both Webkit based browsers. In Firefox, and IE, that technique didn’t work. It seems that IE requires style sheets to be added using the createStyleSheet method, and Firefox is picky, and requires the stylesheets be injected into the <head/> element. Fortunately, a google search turned up a StackOverflow post giving a cross-browser technique for injecting style sheets.

That was the first problem solved. The bigger problem was the links not working. In Firefox, clicking the links showed 404 errors in the page. In IE, they just didn’t work at all.

The cause of this problem lay in the code that takes the html returned by our server and injects it into our customers page. That code has to rewrite all links to make them use hash bangs, so that we can intercept the clicks and post back to our server rather than the customers. In the process of rewriting we were using the document.location.origin property. Turns out, that’s only supported by Webkit browsers. Once again, StackOverflow had the solution.

The problems should all hopefully now be fixed, and welcomehallchurch.org/sermons powered by TruthVine should be working across all three major browsers.

Next time I’ll remember to test on all three browsers first before launching!

Friday, 8 March 2013

Build a Startup in a Week–Mission Accomplished!

This week Rob Ashton and I have been battling against the clock to get a minimum viable product for my startup TruthVine out of the IDE and into the hands of customers in five days.

At 3:42 PM this afternoon, we declared victory:

There were some course adjustments along the way, as you would expect in a project like this. By the end of yesterday, I concluded that I wasn’t going to get my streamlined audio recording tool completed, so to make sure we had something to ship by the end of the week, I decided to put that on hold.

Today we focused all our efforts on getting the TruthVine Admin website and the embedding experience ready for use. And I believe we succeeded. Rob wrote a migration tool to take all the existing sermon data from my own church website (which I manage) and put it into the new TruthVine database. Having deployed the final builds of the software to our EC2 server, I then replaced the sermon display code in the website with TruthVine’s magic script. Two minutes later it was live. You can visit welcomehallchurch.org/sermons to see for yourself. Of course, there’s still a lot left to be done, styling being the most obvious thing – but that’s the point of a minimal viable product. It’s now out there in the wild, and I can start gathering feedback to determine where to focus my efforts next.

This week has been great fun, though hard work. I’d like to thank Rob again for all outstanding efforts. He has given me a great head start. But now the real work begins: marketing TruthVine, and building it into a self-sustaining business.

Oh – and by the way - if you know a church who might be interested in trying this out, send them to me, and I’ll hook them up with a free trial.

Why I chose RavenDb for my startup

In my post the other day about my choices of technological underpinnings for my startup, TruthVine, there was one choice I omitted to mention. I didn’t say which database I had decided upon.

In fact it was a decision which took no consideration at all: having worked with RavenDb on the inside and from the outside, it was my immediate choice. Here’s why.

RavenDb stays out of the way

RavenDb is like a waiter at the best kind of restaurant. It serves your data with the minimum of fuss and gets out of the way. Unlike certain persistence technologies I could mention, there is barely any configuration involved, and not a mapping in sight. You just hand RavenDb an object or any shape or size, and RavenDb stores it. You murmur an object’s id, and RavenDb has it on your plate in an instant, child collections and all.

RavenDb is a document database. That means that you don’t need to declare a schema upfront. Whenever you hand RavenDb an object it simply serializes it to JSON format, and stores it as a blob in its persistence engine. The benefit I see from this is greatly reduced pain when deploying updates to my code, as I won’t need to worry about sql migration scripts. I can add things to my objects with impunity, and for other situations, RavenDb has very nice document patching support.

As as you’d expect, given RavenDb’s provenance, the RavenDb .Net client is awesome. It has full support for the unit-of-work pattern and transactions. Thus any entities you load within a session are tracked, and any that have changed when you save the session are sent to the database in a single transaction. Naturally, the RavenDb client has LINQ support too, with paging in queries being especially trivial to implement.

Here’s a complete snippet showing everything you need to store and retrieve objects from RavenDb.

class RavenDbDemo
{
    public void Demonstrate()
    {
        // DocumentStore is a heavy-weight object usually created once per application
        var documentStore = new DocumentStore() {Url = "http://myravendbserver.com"};
        documentStore.Initialize();

        // session objects are light-weight and are created per transaction
        using (var session = documentStore.OpenSession())
        {
            var person = new Person()
                {
                    Name = "Samuel Jack",
                    FavouriteDatabase = "Sql Server"
                };

            session.Store(person);
            session.SaveChanges();
        }

        using (var session = documentStore.OpenSession())
        {
            var person = session.Query<Person>()
                .First(p => p.Name == "Samuel Jack");

            person.FavouriteDatabase = "RavenDb";

            session.SaveChanges();
        }
    }

    public class Person
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public string FavouriteDatabase { get; set; }
    }
}

Indexing is largely automatic

One thing this snippet highlights is RavenDb’s awesome indexing support. Whenever you make a new kind of query, RavenDb will automatically create an index for you to query against. In the most recent versions of RavenDb, it will automatically tune the indexes over time, depending on the patterns of queries you make against the database. Of course, you can define more sophisticated indexes explicitly, but often you never need to.

One situation where you will need to create indexes is when you want to take advantage of RavenDb’s Map/Reduce support. This is how RavenDb supports queries which involve aggregating multiple documents, since it doesn’t implement grouping clauses in LINQ queries from the client. The nice thing about the way it does this is that Map/Reduce indexes are persisted just like other indexes, which makes aggregate queries very fast.

And There’s More

There is so much more to like about RavenDb, but I’ll just highlight a few other things which I think will be important to me as a startup.

The first is RavenDb’s replication support. This is important if you want to make sure your application has high availability. Configuring replication is as easy as entering the connection string for the database you want RavenDb to replicate too. Replication also helps enormously with scalability, as you can configure your clients to read from any of the replicas, thus spreading the load, but write to the master database, thus ensuring consistency without generating conflicts.

Next is backup support. RavenDb comes with built in support for doing backups to Amazon S3, or Amazon Glacier. You just have to tell it the bucket you want to write to, and your API keys, and off it goes.

The level of support available is always an important consideration when choosing to adopt a product, and RavenDb has great support, both from the RavenDb community who hang out on the RavenDb group, and from Ayende and the rest of the Hibernating Rhinos team. RavenDb is an open source project (using the AGPL license, so you must buy a license if you’re not willing to open-source your own code) and the community are very active in contributing to the project.

I should mention that, if RavenDb has one failing, the documentation is not as good as it might be. The situation has improved a lot recently, and I understand a couple of books are in progress. Most of the time RavenDb just works, but if you stray too far from the beaten path, you might find yourself relying on the community to help you understand what’s going on. Having the code available certainly helps, and, as I said, the community are very responsive.

Finally, I can’t resist a plug for the Management UI (in which, if you press me, I might admit to having played a part!).

image

I love the fact that you scan scroll through your entire documents collection, or through all the results of a query, with the client paging in the data as necessary.

Full disclosure: Whilst these opinions are entirely my own, and I do not believe them to be prejudiced by any other factors, I have been offered a RavenDb license by Hibernating Rhinos in exchange for setting them out in this blog post. I am also a freelance contributor to the RavenDb project.