Tuesday, 22 July 2014

Could not copy the file manifest because it was not found

This is an old chestnut that has maddened me for quite some time. It all starts with the error message

  • C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets(4453, 5): error MSB3030: Could not copy the file "bin\Release\myapp.exe.manifest" because it was not found. 
  • Project src\mysolution\myapp\myapp.csproj failed. 
  • Project src\mysolution\mysolution.sln failed. 

It almost certainly happens when you are doing the following:

  • Using msbuild directly, rather than Visual Studio "right click" (e.g. you are using Team City)
  • Have a solution with a web application and some other application types (e.g. a console app)
  • Are using the Target "Publish" to publish the website

For example, here are the TC settings that cause the problem for me:


I'm also using a solution that has this structure

  • MySolution
    • MyConsoleApp
    • MyWebApp

MyWebApp has a publish profile setup called "PublishToDisk". If I build or publish from Visual studio, everything is fine. If I build from Team City, I get the errors above.

I've known the cause of the problem for ages. The blanket "Publish" target is being applied to every project in the solution that might be publishable. That includes my console application. My console app is not setup for publishing however, nor do I want it to be. I do, however, want it to be built during the Team City process, as the app will get copied elsewhere via the packaging process in later stages.

However the possible solutions are not so obvious. running msbuild separately on myConsoleApp.csproj and MyWebApp.csproj seems ridiculously inefficient. Making my console application a click once app just to stop a build failure seems equally silly. By far the best solution I've found is to edit your myconsoleapp.csproj file and add the following section

<PropertyGroup>
    <GenerateManifests>true</GenerateManifests>
</PropertyGroup>

You can add this just before the ItemGroup for reference includes.

This should be enough to keep to allow your application to build without a load of very awkward feeling bodges.

Incidentally - this problem is one that occurs if you try to do this publishing process with Orchard via TC, so would solve that scenario too.

Tuesday, 15 July 2014

Going Native is All Too Easy

We tend to fall into the same traps over time, not matter how much we try. When I was a consultant, it was very easy to correct a client who demanded technical solutions instead of listing their business objectives. It was my job to re translate that back into "what is the real requirement here".

Now I've been working for an architect at a single company for two years, I find myself falling into the traps that I used to help others avoid. In designing a new profile service a group of three architects, plus other contributors discussed the proposed structure. We went over all the technical implications, and we felt we understood what the business need was quite well thank you, including what would need to be in an MVP, and what could be deferred to later.

Four months on and I find myself in a very enlightening meeting with key business users, who have a far better understanding of what they need than I did, despite having "done my research". I find that several of the decisions I made, while valid in their way, just didn't go far enough to addressing the business need.

It is a timely reminder that the developer (no matter how well in tune with the business he believes himself to be) is ultimately far more focused on a technical challenge and "elegant solutions" than he is with what the end consumers want.

Lesson Learned: If you think you have a solution to the business problem, ask yourself "have I sat in a room for an hour with four business user who have no interest in how it is done, but only what it lets them do?"

Monday, 14 July 2014

Pros and Cons: Comparing RavenDB and FoundationDB

We've recently been evaluating options for storage for a new profiles micro-service. The original prototype for this was produced in Raven, but recently other teams within the business have been having some level of success with FoundationDB. While RavenDB is touted as a "Document Store", FoundationDB claims to be simply a "Key/Value pair store. Below is my assesment of the pros and cons of each.

RavenDB


Pro
  • Excellent .NET client API with extensibility points, providing easy developer learning curve
  • Designed as Document Store
  • Provides Index/Map/Reduce
  • Stores natively as JSON
  • Good Read Performance
  • Fits excellently into integration testing, due to in memory db option designed for testing
  • Automatically generates Ids for records
  • Well presented web based management studio
  • Raven Server has a good console where you can see requests/response times and what indexes are used to resolve queries

Con

  • Cannot test replication, sharding or authenticated access functions without purchasing licenses and licenses are needed for anything other than development (UAT would need licenses)
  • Some concerns over the dependence of the RavenDB project on one key developer
  • Some concerns about the robustness of the testing of the product and its unproven track record in enterprise solutions (posts like this are easy to find
  • Yet another product for devops to support
  • Need to understand the “eventually consistent” model well when designing solutions

FoundationDB


Pro

  • We already use it in several other services (we have experience of it)
  • Better licensing terms (by far) All features free outside production, and production licensing terms essentially means it is currently free for us to use
  • Full ACID compliance
  • Has both Consistency and Availability during Partitioning (assuming it isn’t a catastrophic failure)
  • Built in transaction retries
  • Support from FDB team is excellent
  • Excellent read performance both single reads and range reads are only marginally slower
  • Transaction isolation level is serializable
  • Simple to scale horizontally

Con

  • Designed as a Key/Value pair store rather than Document Store
  • Weak .NET support (only 3rd party .NET client wrapper on top of C) with less .NET documentation/support. NET not considered first class citizen of FoundationDB
  • Constraints on deployment - cannot be deployed in IIS, must be self-hosted - loss of IIS specific features such as graceful request handling, automatic app pool recycles/mem management
  • Cannot run in multiple AppDomains on same process
  • Like Raven, also an Alpha product, though we have less concerns about the composition of the development team
  • Does not generate IDs, so a separate “ID Generation Service” would be required (or switch entire platform to GUIDs with the resulting data migrations
  • No nice ‘management’ interface - you need to roll your own admin tool


To summarise the differences at high level I would say that RavenDB is great for .NET developers to rapidly write applications against, but may provide a problematic operational experience, and paying before you can test replication/"clustering" successfully is a tough ask. Conversely, FoundationDB has a really steep curve to get going with .NET, you have to live without several normally expected comforts, but does provide a compelling operational case from the ACID/clustering point of view (though, it too is an alpha, but its testing thoroughness seems far better).

As for which is "better", well, it really depends on purpose. It looks like a case of weighing up "Fast, easy development" versus "fast easy ongoing operational support". As a business we are currently leaning towards the operational ease, as products tends to spend most of in production, not development (unless you are the UK government of course).

Monday, 23 June 2014

It's great when your tools make you more effective...

Today I wrote some code, which my integration tests showed a regression in. I fixed this and merged to Git. Hub. Team City automatically build and versioned a package, which Octopus Deploy deployed to dev01. I then ran my load tests, which showed things had slowed down. I checked out the problem using New Relic, which showed traces for the slow transactions, along with our correlation token for the slow requests. I then used Kibana to find all log entries stored in Elastic Search with that correlation token, which highlighted the area causing the slow down.

I love it when a plan comes together....

Thursday, 4 July 2013

A simple Orchard module to inject a diagnostics shape into every page of your Orchard site

Orchard has some great extensibility hooks. This post will show you how to very quickly use one to add a diagnostic section (like below) to the top of each page.


This uses:
  • A feature in a module: to toggle on/off the ability
  • A class implementing Orchards FilterProvider
  • A view file to be used as a shape

First thing to do is create a new module, with a feature inside. If you need a primer, try the Orchard Walkthrough and the Hello World Module example. This article assumes that you create a module called "MyModule", and that you make a feature called "MyModule.SessionChecker"

To write output to every page we can hook into the FilterProvider class provided by the Orchard framework. Orchard.Mvc.Filters.FilterProvider is an abstract class that implements IDependency. This means that if your feature implements the class, it will automatically be wired up by Orchard at run time. All you need to do is fill in the methods of the class in your own inherited version, like below.


Code:
    [OrchardFeature("MyModule.SessionChecker")]
    public class SessionCheckerFilter : FilterProvider, IResultFilter
    {
        private readonly IWorkContextAccessor _workContextAccessor;
        private readonly IShapeFactory _shapeFactory;

        public SessionCheckerFilter(IWorkContextAccessor workContextAccessor, IShapeFactory shapeFactory)
        {
            _workContextAccessor = workContextAccessor;
            _shapeFactory = shapeFactory;
        }

        public void OnResultExecuting(ResultExecutingContext filterContext)
        {
            if (filterContext.Result as ViewResult == null) {
                return;
            }

            _workContextAccessor.GetContext(filterContext).Layout.Zones["Body"].Add(_shapeFactory.Create("diagnosticview"), ":before");
        }

        public void OnResultExecuted(ResultExecutedContext filterContext) { }
    }

The key things we are doing here are

  • Using the OnResultExecuting method to ensure we hook in as the result is being formed
  • Creating a new shape and returning it inside the body zone of the page 
The use of shapes is a massive topic in Orchard, and there are others out there better suited to talking about them. For this purpose it is enough to say that we use the IShapeFactory to create an arbitrary shape. The name of this shape is the name of a razor view that we need to create in our views folder in the module.

Add the file diagnosticsview.cshtml to the "views" folder in your module. The shape factory will find and use this shape. I've made my example as follows:

 <style> 
   .SessionChecker {  
     position:absolute;  
     left:0px;  
     top:0px;  
     z-index:100;  
     border:solid 1pt #AAAAAA;  
     background-color: #EEEEEE;  
     padding: 5px;  
     font-family: consolas, arial;  
     font-size: 10pt;  
   }  
   .SessionChecker b {  
     font-weight: bold;  
   }  
 </style>
 <div class="SessionChecker">  
   Current Value for Session["TestSessionManagement"]: @Session["TestSessionManagement"]  
 </div>  

And all this does is show the value of a particular session setting I'm interested in, but you could make yours much more interesting. Any loigic more complex than that shown should be done within the FilterProvider class you implemented, and be passed to the view as a model

Lastly, make sure to enable your module/feature to see the results. When you don't want them appearing any more, disable the module! Excellent for temporary diagnostic scenarios. For added bonus - only show it when the current user is an admin!

Thursday, 6 June 2013

Gotcha in Orchard CMS RoutesDescriptor when using Multi-Tenancy

It's been a while since I posted, and I've been using Orchard CMS a lot among other things. I came across a rather trickysome problem today, hopefully this post will help others find the resolution quicker than I did. In orchard you can Implement IRouteProvider in any module you write. This is basically a wrapper for MVC routes, and works really well. For example, the route defined below is for custom handling in the event of errors.

public class ErrorHandlingRoutesProvider : IRouteProvider
    { 
        public IEnumerable<routedescriptor> GetRoutes() 
        { 
            return new[]{  
                new RouteDescriptor{ 
                    Name = "ErrorRoute",  
                    Priority = 1,                     
                    Route = new Route( 
                        "Error", 
                        new RouteValueDictionary{ 
                            {"action", "ErrorPage"}, 
                            {"controller", "ErrorHandler"}, 
                            {"area", "BG.Shared.ErrorHandling"} 
                        }, 
                        new RouteValueDictionary(),//constraints (none here) 
                        new RouteValueDictionary{ 
                            {"area", "BG.Shared.ErrorHandling"} 
                        }, 
                        new MvcRouteHandler()) 
                }; 
        }

This works as intended in a single site. However, when you have two tenants using the same module, this will fail with an error similar to the following:

System.ArgumentException: A route named 'ErrorRoute' is already in the route collection. Route names must be unique.
Parameter name: name 
   at System.Web.Routing.RouteCollection.Add(String name, RouteBase item) 
   at Orchard.Mvc.Routes.RoutePublisher.Publish(IEnumerable`1 routes) in d:\Workspaces\GitHub\src\Orchard\Mvc\Routes\RoutePublisher.cs:line 100
   at Orchard.Environment.DefaultOrchardShell.Activate() in d:\Workspaces\GitHub\src\Orchard\Environment\DefaultOrchardShell.cs:line 48
   at Orchard.Environment.DefaultOrchardHost.ActivateShell(ShellContext context) in d:\Workspaces\GitHub\src\Orchard\Environment\DefaultOrchardHost.cs:line 156
   at Orchard.Environment.DefaultOrchardHost.CreateAndActivateShells() in d:\Workspaces\GitHub\src\Orchard\Environment\DefaultOrchardHost.cs:line 135

The workaround is to comment out the "Name" attribute of the RouteDescriptor, as follows
public IEnumerable<RouteDescriptor> GetRoutes() 
        { 
            return new[]{  
                new RouteDescriptor{ 
                     
                    //Name = "ErrorRoute", //This doesn't work in Multi-Tenancy 
                    Priority = 1,                     
                    Route = new Route( 
                        "Error", 
                        new RouteValueDictionary{ 
                            {"action", "ErrorPage"}, 
                            {"controller", "ErrorHandler"}, 
                            {"area", "BG.Shared.ErrorHandling"} 
                        }, 
                        new RouteValueDictionary(),//constraints (none here) 
                        new RouteValueDictionary{ 
                            {"area", "BG.Shared.ErrorHandling"} 
                        }, 
                        new MvcRouteHandler()) 
                }      
            }; 
        }
I've started investigating this with the Orchard team, but the workaround doesn't really appear to have any drawbacks.