AMBROSIA/Samples/HelloWorld/HOWTO-WINDOWS.md

6.0 KiB

How to run the HelloWorld Sample (on Windows with .NET Core)

This sample shows two immortals communicating, a client and a server. You can build and run it locally to get a quick idea of how Ambrosia operates. The solution contains two alternate versions of the client (Client1 and Client2), only one of which is used at a time. Client1 demonstrates basic communication, while Client2 demonstrates nondeterministic input using an impulse handler.

Quick Build

The sample uses the AmbrosiaLibCS NuGet package to import the necessary Ambrosia binaries. These packages are picked up automatically from the public NuGet feed, so there are no extra steps required to import them.

  • Build HelloWorld.sln in Visual Studio, using configuration Debug and platform x64.

As part of a full build, Ambrosia generates code for the interface proxies. To make this sample easy to run, we have already included the generated code, so you don't have to run code generation just to build and run the HelloWorld sample. However, if you want to experiment with it or make any changes to the interfaces, you can run code generation yourself as described in the section "Full Build w/ Code Generation" below.

Getting the Ambrosia tool binaries

To run HelloWorld you'll also need the Ambrosia tools that are distributed in compressed folder. To get these,

  • Download the compressed folder Ambrosia-win.zip
  • Unpack it somewhere on your disk; for example, C:\Ambrosia-win\
  • Set the %AMBROSIATOOLS% environment variable to point to that directory

Running HelloWorld

For the purpose of this tutorial, we'll assume the following parameters:

  • Log directory: C:\logs\
  • Client instance name: client
  • Client ImmortalCoordinator receive port: 1000
  • Client ImmortalCoordinator send port: 1001
  • Client ImmortalCoordinator CRA port: 1500
  • Server instance name: server
  • Server ImmortalCoordinator receive port: 2000
  • Server ImmortalCoordinator send port: 2001
  • Server ImmortalCoordinator CRA port: 2500

Storage Connection String

Ambrosia uses an Azure table to maintain and discover information about your application's immortals and their status. To access this information, all Ambrosia tools and libraries need a connection string to an Azure storage account stored in the environment variable %AZURE_STORAGE_CONN_STRING%. To run this sample, you must therefore create an Azure Storage account if you don't already have one, and set the environment variable to contain its connection string.

Registering the Immortal instances

Before running the application, you need to register each Immortal instance so that other Immortal instances can find them. Open a command prompt and enter the following commands:

cd %AMBROSIATOOLS%\x64\Release\netcoreapp2.0\
dotnet Ambrosia.dll RegisterInstance -i=client -rp=1000 -sp=1001 -l=C:\logs\
dotnet Ambrosia.dll RegisterInstance -i=server -rp=2000 -sp=2001 -l=C:\logs\

You should see messages "The CRA instance appears to be down. Restart it and this vertex will be instantiated automatically". That means everything is working as expected! We have not started those instances yet - once we start them they'll register automatically.

Running the application

To run the HelloWorld application, you will need to run four command-line processes, each in a separate console window: the HelloWorld client Immortal, the HelloWorld server Immortal, and two ImmortalCoordinator processes, one for each Immortal.

To run the server ImmortalCoordinator, in the first console window:

cd %AMBROSIATOOLS%\x64\Release\netcoreapp2.0
dotnet ImmortalCoordinator.dll --instanceName=server --port=2500

To run the client ImmortalCoordinator, in the second console window:

cd %AMBROSIATOOLS%\x64\Release\netcoreapp2.0
dotnet ImmortalCoordinator.dll --instanceName=client --port=1500

To run the HelloWorld server, in the third console window:

cd Server\bin\x64\Debug\netcoreapp2.0
dotnet Server.dll

To run the HelloWorld client, in the fourth console window:

cd Client1\bin\x64\Debug\netcoreapp2.0
dotnet Client1.dll

After starting all four processes, you should see your client and server communicate with each other! Specifically:

  • The console of the server process prints Received message from a client: Hello World 1!
  • The console of the client process prints Press any key to continue
  • (Now press a key in the client process console window)
  • The console of the server process prints Received message from a client: Hello World 2!
  • The console of the server process prints Received message from a client: Hello World 3!

Clearing state and re-running

If you want to run Hello World a second time, it is not enough to just restart the immortals! They will just resume running where they left off (at the end of Hello World, or wherever else they were). So, to start over, you have to clear the state. It's simple:

  • Delete the contents of the C:\logs directory.

Optionally, you can also delete the registrations in the Azure table:

cd %AMBROSIATOOLS%\x64\Release\netcoreapp2.0\
dotnet UnsafeDeregisterInstance.dll server
dotnet UnsafeDeregisterInstance.dll client

Of course, if you delete those, you have to re-register them in order to run HelloWorld again.

Full Build w/ Code Generation

Ambrosia generates code for the interface proxies. To make this sample easy to run, we have already included the generated code, so you don't have to run code generation just to build and run the HelloWorld sample. However, if you want to experiment with it or make any changes to the interfaces, here is how you can run the code generation step.

  1. Build the projects IClient1, IClient2 and IServer. This generates the binaries used by the code generation step.

  2. Run code generation by executing Generate-Assemblies-NetCore.ps1. This overwrites the content of the projects Client1Interfaces, Client2Interfaces and ServerInterfaces with generated code.

  3. Build HelloWorld.sln. This now picks up the freshly generated source files.