Sunday, 8 January 2017

Programming the ADS-FX2 solenoid controller with JMRI

It is possible to program the ADS-FX2 solenoid controller with JRMI with the following procedure:

1. Open PanelPro
2. Open Power Control (Tools > Power Control)
3. Ensure the power to the track is on
4. Open Tools > Tables > Turnouts
5. Add the IDs of the turnouts that you wish to program (Click Add, then enter the hardware address and save)
6. Open a throttle (Tools > Throttles > New Throttle)
7 Set the switch on the ADS-FX2 for the desired solenoid to Program
8. In the throttle window enter the desired address into the address panel and press Set
9. Go to the Turnouts table window and Issue the Thrown / Closed command against the matching address that you entered in the earlier step
10. Set the switch on the ADS-FX2 back to Run
11. Try throwing the points using the Turnout table window

Tuesday, 3 January 2017

DocumentDB protocol support for MongoDB

DocumentDb now supports the MongoDB protocol.

I did a test before Christmas using a very slightly modified NEventStore with Mongo persistence routed to DocumentDB. Everything worked fine at the time, now after Christmas something is awry. I wrote a test to isolate the problem and it appears that when persisting a long value (with the expectation it is serialized as an Int64, it is written as an Int32).

I can't figure out what has changed. Perhaps it is my code, or has Microsoft done something "under the hood"?

I tried the code below. The two connection strings alternate between the local "real" Mongo 3.4 server and the DocumentDB with Mongo support in Azure. I added the mongocsharprdriver version 1.10.0 (the one I used before Christmas) and then the very latest and no runtime difference was found.

The code below writes the long as an Int32 in DocumentDb, but as a long in the local MongoDB.


using System;
using System.Linq;
using System.Security.Authentication;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using MongoDB.Driver.Linq;

namespace DocumentDb.Mongo.Test
{
    internal class Program
    {
        static void Main()
        {
            const string connectionString = @"mongodb://<my Azure MongoDB DocumentDB connection>/?ssl=true&sslverifycertificate=false";
            // const string connectionString = @"mongodb://localhost:27017/test";
            const string indexName = "_id";
            var clientSettings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
            clientSettings.SslSettings = new SslSettings() { EnabledSslProtocols = SslProtocols.Tls12 };
            var client = new MongoClient(clientSettings);
            var db = client.GetServer().GetDatabase("test");
            var collection = db.GetCollection("testcollection");
  
            const long testValue = 1;
            var doc = new BsonDocument
            {
                {indexName, testValue}
            };

            collection.Update(
                Query.EQ(indexName, testValue),
                Update.Replace(doc),
                UpdateFlags.Upsert);
                
            doc = collection.AsQueryable().First();
            Console.WriteLine($"Value={doc[indexName].AsInt64}");
        }
    }
}

Wednesday, 28 December 2016

Beyond Compare with TFS

The article describing how to compare various Version Control Systems with BeyondCompare is here.

TEAM FOUNDATION SERVER (TFS)

Diff

  1. In Visual Studio Choose Options from the Tools menu.
  2. Expand Source Control in the treeview.
  3. Click Visual Studio Team Foundation Server in the treeview.
  4. Click the Configure User Tools button.
  5. Click the Add button.
  6. Enter ".*" in the Extension edit.
  7. Choose Compare in the Operation combobox.
  8. Enter the path to BComp.exe in the Command edit.
  9. In the Arguments edit, use:
    %1 %2 /title1=%6 /title2=%7

3-way Merge Pro only

  1. Follow steps 1-6 above.
  2. Choose Merge in the Operation combobox.
  3. Enter the path to BComp.exe in the Command edit.
  4. In the Arguments edit, use:
    %1 %2 %3 %4 /title1=%6 /title2=%7 /title3=%8 /title4=%9

2-way Merge

Use the same steps as the 3-way merge above, but use the command line:
%1 %2 /savetarget=%4 /title1=%6 /title2=%7

Monday, 19 December 2016

Device Manager driver update gets stuck at "Searching Online for Software"

https://answers.microsoft.com/en-us/windows/forum/windows_8-update/windows-update-not-updating-stuck-on-checking/da51ddbc-40ff-4ed9-b2a7-9381843728a1

Wednesday, 14 December 2016

Event Store - my learnings

I have been evaluating Event Store and thought I'd write my learnings. The context is based upon an Order Processing system, which receives Orders (OrderCreated) and processes them through their lifecycle.

 1. Hard deletes are really hard! If you are testing and creating streams and deleting them, if you do a hard delete you really CANNOT recreate a stream. Of course, this is not a natural thing to do in a real world environment, but beware if playing around. The only way to get around it is to use a new DB. 

2. The browser window does a lot of caching. I (soft) deleted a stream and then went back to the Stream Browser window. It still displayed the stream I deleted and when I clicked through it displayed the events within the stream. This led me to hard delete it which caused other problems. In reality, the browser is caching all the information. Either use Developer Tools to clear the cache or use the API: the stream HAS been deleted.

3. When modifying a projection, reset it. I had errors when I modified a projection and didn't reset it. 

4. Consistency is guaranteed within a stream, not across them. If in pseudocode you write:

for (var i=1; i<6; i++)
{
    CreateStream(i);
}
you will not necessarily see 5,4,3,2,1 in the Most Recently Created Streams and projections upon the Streams will be sequenced accordingly.
This is because the parallelism of the writes means that any that were initiated at almost identical times will be written to the log as each task completes. If you were to add a small sleep in the for loop you would see them being sequenced in the same order as the API calls.

Remember, consistency is guaranteed WITHIN a stream, not ACROSS a stream. Events within a stream will be written in the sequence that they are received.

This consistency guarantee may help you decide how to arrange your streams. If my stream was AllOrderEvents, and it contained all of the events for all of the orders, then this may incur a performance hit as concurrent writers will all be trying to write into one log for all orders and they may get version conflicts. We don't care about the exact sequencing of one order to another, but we do care about the sequencing of events within an order.

Furthermore, remember that in a distributed event-driven system, we should not rely upon Message Ordering. Some message buses may provide ordered messaging, but they will do this at a cost to performance and storage.

Event Store - the fromCategory projection does not work / does not project

I wrote a projection to enumerate all streams beginning "Order" and pull out how many orders were created (by having the event OrderCreated in their stream). This was a simple way of building up a projection of orders in the system.

fromCategory("Order")
    .foreachStream()
   .when({
        $init: function() {
           return { count: 0 }
        },
        "OrderCreated": function(state, event) {
          emit('newOrders', 'order', { 'orderReference' : '1' })
        }
  })


And for love nor money I could not get this to work.

In the end this answer steered me: you have to config EventStore not only to run projections but also to start the standard projections.
EventStore.ClusterNode.exe --run-projections=all --start-standard-projections=true

Saturday, 10 December 2016

Unturned: Running a Console Application with arguments as a Windows Service

Unturned requires you to run a console application as a server.
If you want to start this automatically when a Windows Server restarts without any GUI interaction then it is necessary to run it as a Windows Service.

I tried a couple of tools and found that nssm.exe worked best. It allows you to specify a Console.exe and include startup parameters.
Other tools such as RunAsService could not handle the fact that the service did not respond in a timely fashion to the Service Control Manager.