зеркало из https://github.com/microsoft/AMBROSIA.git
HelloWorld: Finish up BASH how to guide
This commit is contained in:
Родитель
e154c5e343
Коммит
27b2f88ab5
|
@ -25,12 +25,22 @@ namespace Client1
|
|||
protected override async Task<bool> OnFirstStart()
|
||||
{
|
||||
_server = GetProxy<IServerProxy>(_serverName);
|
||||
_server.ReceiveMessageFork("Hello World 1!");
|
||||
Console.WriteLine("Press any key to continue");
|
||||
|
||||
|
||||
_server.ReceiveMessageFork("\n!! Client: Hello World 1!");
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine("\n!! Client: Press any key to continue");
|
||||
Console.ResetColor();
|
||||
|
||||
Console.ReadKey();
|
||||
_server.ReceiveMessageFork("Hello World 2!");
|
||||
_server.ReceiveMessageFork("Hello World 3!");
|
||||
Console.WriteLine("Press any key to end");
|
||||
_server.ReceiveMessageFork("\n!! Client: Hello World 2!");
|
||||
_server.ReceiveMessageFork("\n!! Client: Hello World 3!");
|
||||
|
||||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||||
Console.WriteLine("\n!! Client: Press any key to end");
|
||||
Console.ResetColor();
|
||||
|
||||
Console.ReadKey();
|
||||
Program.finishedTokenQ.Enqueue(0);
|
||||
return true;
|
||||
|
|
|
@ -18,31 +18,54 @@ Now you have binaries built under the paths `Server/publish`,
|
|||
`Client1/publish`, and `Client2/publish`. The two clients are
|
||||
*different* examples, and only one or the other should be run at a time.
|
||||
|
||||
Running
|
||||
-------
|
||||
|
||||
Registering
|
||||
-----------
|
||||
### Super quickstart for the impatient
|
||||
|
||||
If you're feeling lucky, you can try running the setting
|
||||
AZURE_STORAGE_CONN_STRING and then running two communicating services
|
||||
locally in one terminal like so:
|
||||
|
||||
./run_helloworld_both.sh
|
||||
|
||||
Or you can tease it apart and open the client and server separately,
|
||||
in separate terminal windows:
|
||||
|
||||
./run_helloworld_client.sh
|
||||
./run_helloworld_server.sh
|
||||
|
||||
After you run, you'll want to cleanup the logs (`ambrosia_logs/`)
|
||||
before running again, or the system will think it's recovering from a
|
||||
failure and still part of the previous run.
|
||||
|
||||
### Longer version
|
||||
|
||||
In order to develop your own AMBROSIA services we'll need to walk
|
||||
through the steps in a bit more detail. There are three main steps.
|
||||
|
||||
#### (Steps 1/3) Registering
|
||||
|
||||
Before we can run the client/server, we need to register metadata
|
||||
about these AMBROSIA instances with in the cloud table storage. Pick
|
||||
a name for your client and server instances.
|
||||
|
||||
Ambrosia RegisterInstance -i myclient --rp 2000 --sp 2001 -l ./logs
|
||||
Ambrosia RegisterInstance -i myserver --rp 2000 --sp 2001 -l ./logs
|
||||
Ambrosia RegisterInstance -i myclient --rp 1000 --sp 1001 -l ./ambrosia_logs
|
||||
Ambrosia RegisterInstance -i myserver --rp 2000 --sp 2001 -l ./ambrosia_logs
|
||||
|
||||
We've told AMBROSIA that it will use `./logs` for storing logs locally,
|
||||
but in a production environment of course logs would need to be on a
|
||||
remotely-mounted file system that is durable even when the machine fails.
|
||||
We've told AMBROSIA that it will use `./ambrosia_logs` for storing
|
||||
logs locally, but in a production environment of course logs would
|
||||
need to be on a remotely-mounted file system that is durable even when
|
||||
the machine fails.
|
||||
|
||||
|
||||
Running
|
||||
-------
|
||||
#### (Step 2/3) Running an instance.
|
||||
|
||||
First let's run the server. Open a terminal, and let's set up some of
|
||||
the configuration information that will be used by the
|
||||
`runAmbrosiaService.sh` script to launch your process.
|
||||
|
||||
export AMBROSIA_INSTANCE_NAME=myclient
|
||||
export AMBROSIA_IMMORTALCOORDINATOR_PORT=1500
|
||||
export AMBROSIA_INSTANCE_NAME=myserver
|
||||
export AMBROSIA_IMMORTALCOORDINATOR_PORT=2500
|
||||
export AZURE_STORAGE_CONN_STRING=...
|
||||
|
||||
To launch a service we're going to use a convenience script called
|
||||
|
@ -50,12 +73,34 @@ To launch a service we're going to use a convenience script called
|
|||
of AMBROSIA. This handles starting the immortal coordinator and
|
||||
monitorying its health.
|
||||
|
||||
runAmbrosiaService.sh
|
||||
runAmbrosiaService.sh dotnet Server/publish/Server.dll myserver
|
||||
|
||||
You could start ImmortalCoordinator yourself, as well, by using two
|
||||
separate terminals to run:
|
||||
You'll see a lot of output, with output from the coordinator tagged
|
||||
`[ImmortalCoord]`. Eventually, the coordinator reports "Ready" and
|
||||
|
||||
Alternatively, you could start ImmortalCoordinator yourself, by using
|
||||
two separate terminals to run:
|
||||
|
||||
Cleanup
|
||||
-------
|
||||
ImmortalCoordinator -i myserver -p 2500
|
||||
dotnet Server/publish/Server.dll myserver
|
||||
|
||||
#### Running another instance.
|
||||
|
||||
Now you have the server running, but for this to be interesting, we
|
||||
need another client to connect to the server.
|
||||
|
||||
export AMBROSIA_INSTANCE_NAME=myclient
|
||||
export AMBROSIA_IMMORTALCOORDINATOR_PORT=1500
|
||||
export AZURE_STORAGE_CONN_STRING=...
|
||||
runAmbrosiaService.sh dotnet Client1/Publish/Client1.dll myclient myserver
|
||||
|
||||
#### (Step 3/3) Cleanup
|
||||
|
||||
To delete all the metadata we left in the cloud, run the following:
|
||||
|
||||
UnsafeDeregisterInstance myclient
|
||||
UnsafeDeregisterInstance myserver
|
||||
|
||||
Note this is called "unsafe" because one must take great care to not
|
||||
call it while any part of the service may still be running.
|
||||
|
||||
|
|
|
@ -21,7 +21,10 @@ namespace Server
|
|||
|
||||
public async Task<int> ReceiveMessageAsync(string message)
|
||||
{
|
||||
Console.WriteLine("Received message from a client: " + message);
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine("\n!! SERVER Received message from a client: " + message);
|
||||
Console.ResetColor();
|
||||
|
||||
_messagesReceived++;
|
||||
return _messagesReceived;
|
||||
}
|
||||
|
|
|
@ -15,18 +15,6 @@ set -euo pipefail
|
|||
# ------------------------------------------------------------------------------
|
||||
cd `dirname $0`
|
||||
|
||||
# PORTOFFSET: A number to add to all ports to avoid colliding or
|
||||
# reusing recently used ports.
|
||||
# if ! [ ${OFFSET:+defined} ]; then
|
||||
# OFFSET=0
|
||||
# fi
|
||||
# PORT1=$((1000 + OFFSET))
|
||||
# PORT2=$((1001 + OFFSET))
|
||||
# PORT3=$((1002 + OFFSET))
|
||||
# PORT4=$((1003 + OFFSET))
|
||||
# CRAPORT1=$((1004 + OFFSET))
|
||||
# CRAPORT2=$((1005 + OFFSET))
|
||||
|
||||
if ! [ ${OFFSET:+defined} ]; then
|
||||
OFFSET=0
|
||||
fi
|
||||
|
@ -37,22 +25,11 @@ PORT4=2001
|
|||
CRAPORT1=1500
|
||||
CRAPORT2=2500
|
||||
|
||||
ME=`whoami`
|
||||
# ME=`whoami`
|
||||
ME=rrnewton
|
||||
CLIENTNAME=${ME}client${OFFSET}
|
||||
SERVERNAME=${ME}server${OFFSET}
|
||||
|
||||
if ! which Ambrosia 2> /dev/null; then
|
||||
echo "'Ambrosia' not found."
|
||||
echo "You need Ambrosia on your PATH. Please download an AMBROSIA binary distribution."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -e Client1/publish/Client1.dll ]; then
|
||||
echo "Build products don't exist in ./Client1/publish."
|
||||
echo "Did you run ./build_dotnetcore.sh yet?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "--------------------------------------------------------------------------------"
|
||||
echo "HelloWorld with 2 instances all in this machine/container"
|
||||
|
@ -60,24 +37,12 @@ echo " Instance: names $CLIENTNAME, $SERVERNAME"
|
|||
echo "--------------------------------------------------------------------------------"
|
||||
echo
|
||||
|
||||
if ! [ ${SKIP_REGISTER:+defined} ]; then
|
||||
set -x
|
||||
time Ambrosia RegisterInstance -i $CLIENTNAME --rp $PORT1 --sp $PORT2 -l "./ambrosia_logs/"
|
||||
time Ambrosia RegisterInstance -i $SERVERNAME --rp $PORT3 --sp $PORT4 -l "./ambrosia_logs/"
|
||||
set +x
|
||||
fi
|
||||
# Clear logs for this demonstration.
|
||||
rm -rf ./ambrosia_logs/
|
||||
|
||||
echo "Running with AMBROSIA binaries from: "$(dirname `which runAmbrosiaService.sh`)
|
||||
slog=`mktemp server.XXXX.log`
|
||||
jlog=`mktemp client.XXXX.log`
|
||||
|
||||
echo
|
||||
echo "PTI: Launching Server:"
|
||||
set -x
|
||||
AMBROSIA_INSTANCE_NAME=$SERVERNAME AMBROSIA_IMMORTALCOORDINATOR_PORT=$CRAPORT1 \
|
||||
COORDTAG=CoordServ AMBROSIA_IMMORTALCOORDINATOR_LOG=$slog \
|
||||
runAmbrosiaService.sh dotnet ./Server/publish/Server.dll $SERVERNAME
|
||||
|
||||
./run_helloworld_server.sh &
|
||||
set +x
|
||||
pid_server=$!
|
||||
echo "Server launched as PID ${pid_server}. Waiting a bit."
|
||||
|
@ -89,26 +54,22 @@ if ! kill -0 $pid_server 2>/dev/null ; then
|
|||
echo
|
||||
exit 1
|
||||
fi
|
||||
echo
|
||||
echo "PTI: Launching Client1 now:"
|
||||
set -x
|
||||
AMBROSIA_INSTANCE_NAME=$CLIENTNAME AMBROSIA_IMMORTALCOORDINATOR_PORT=$CRAPORT2 \
|
||||
COORDTAG=CoordCli AMBROSIA_IMMORTALCOORDINATOR_LOG=$jlog \
|
||||
runAmbrosiaService.sh dotnet ./Client1/Publish/Client1.dll $CLIENTNAME $SERVERNAME
|
||||
set +x
|
||||
|
||||
echo
|
||||
echo "PTI Client finished, shutting down server."
|
||||
echo "Launching Client1 now:"
|
||||
./run_helloworld_client.sh
|
||||
|
||||
echo
|
||||
echo "Client finished, shutting down server."
|
||||
kill $pid_server
|
||||
wait
|
||||
echo "Everything shut down. All background processes done."
|
||||
|
||||
echo "Attempt a cleanup of our table metadata:"
|
||||
echo "Finally, attempt a cleanup of our table metadata:"
|
||||
set -x
|
||||
UnsafeDeregisterInstance $CLIENTNAME || true
|
||||
UnsafeDeregisterInstance $SERVERNAME || true
|
||||
rm $slog $jlog
|
||||
rm *-coord.*.log
|
||||
set +x
|
||||
|
||||
|
||||
echo "HelloWorld all done."
|
|
@ -0,0 +1,42 @@
|
|||
#!/bin/bash
|
||||
[[ "$AZURE_STORAGE_CONN_STRING" =~ ';AccountName='[^\;]*';' ]] && \
|
||||
echo "Using AZURE_STORAGE_CONN_STRING with account "${BASH_REMATCH}
|
||||
set -euo pipefail
|
||||
cd `dirname $0`
|
||||
|
||||
PORT1=1000
|
||||
PORT2=1001
|
||||
CRAPORT1=1500
|
||||
|
||||
ME=`whoami | sed 's/[^a-zA-Z0-9]//g'`
|
||||
CLIENTNAME=${ME}client
|
||||
SERVERNAME=${ME}server
|
||||
|
||||
if ! which Ambrosia 2> /dev/null; then
|
||||
echo "'Ambrosia' not found."
|
||||
echo "You need Ambrosia on your PATH. Please download an AMBROSIA binary distribution."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -e Client1/publish/Client1.dll ]; then
|
||||
echo "Build products don't exist in ./Client1/publish."
|
||||
echo "Did you run ./build_dotnetcore.sh yet?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "HelloWorld Client Starting, name $CLIENTNAME"
|
||||
echo
|
||||
|
||||
set -x
|
||||
Ambrosia RegisterInstance -i $CLIENTNAME --rp $PORT1 --sp $PORT2 -l "./ambrosia_logs/"
|
||||
set +x
|
||||
|
||||
clog=`mktemp client-coord.XXXX.log`
|
||||
|
||||
set -x
|
||||
AMBROSIA_INSTANCE_NAME=$CLIENTNAME AMBROSIA_IMMORTALCOORDINATOR_PORT=$CRAPORT1 \
|
||||
COORDTAG=CoordCli AMBROSIA_IMMORTALCOORDINATOR_LOG=$clog \
|
||||
runAmbrosiaService.sh dotnet Client1/Publish/Client1.dll $CLIENTNAME $SERVERNAME
|
||||
set +x
|
||||
echo "HelloWorld Client finished."
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
[[ "$AZURE_STORAGE_CONN_STRING" =~ ';AccountName='[^\;]*';' ]] && \
|
||||
echo "Using AZURE_STORAGE_CONN_STRING with account "${BASH_REMATCH}
|
||||
set -euo pipefail
|
||||
cd `dirname $0`
|
||||
|
||||
PORT3=2000
|
||||
PORT4=2001
|
||||
CRAPORT2=2500
|
||||
|
||||
ME=`whoami | sed 's/[^a-zA-Z0-9]//g'`
|
||||
SERVERNAME=${ME}server
|
||||
|
||||
if ! which Ambrosia 2> /dev/null; then
|
||||
echo "'Ambrosia' not found."
|
||||
echo "You need Ambrosia on your PATH. Please download an AMBROSIA binary distribution."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! [ -e Client1/publish/Client1.dll ]; then
|
||||
echo "Build products don't exist in ./Client1/publish."
|
||||
echo "Did you run ./build_dotnetcore.sh yet?"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "HelloWorld Server Starting, name $SERVERNAME"
|
||||
echo
|
||||
set -x
|
||||
Ambrosia RegisterInstance -i $SERVERNAME --rp $PORT3 --sp $PORT4 -l "./ambrosia_logs/"
|
||||
set +x
|
||||
|
||||
slog=`mktemp server-coord.XXXX.log`
|
||||
|
||||
set -x
|
||||
AMBROSIA_INSTANCE_NAME=$SERVERNAME AMBROSIA_IMMORTALCOORDINATOR_PORT=$CRAPORT2 \
|
||||
COORDTAG=CoordServ AMBROSIA_IMMORTALCOORDINATOR_LOG=$slog \
|
||||
runAmbrosiaService.sh dotnet Server/publish/Server.dll $SERVERNAME
|
||||
set +x
|
|
@ -133,7 +133,7 @@ function tail_tagged() {
|
|||
# Side effect: runs a tail proycess in the background
|
||||
function start_immortal_coordinator() {
|
||||
echo " $TAG Launching coordinator with: ImmortalCoordinator" $*
|
||||
if ! which ImmortalCoordinator; then
|
||||
if ! which ImmortalCoordinator 2> /dev/null; then
|
||||
echo " ERROR $TAG - ImmortalCoordinator not found on path!"
|
||||
exit 1
|
||||
fi
|
||||
|
@ -150,28 +150,36 @@ function start_immortal_coordinator() {
|
|||
fi
|
||||
echo " $TAG Redirecting output to: $COORDLOG"
|
||||
|
||||
# OPTION (1): Bound logs, but complicated.
|
||||
# ----------------------------------------
|
||||
if which rotatelogs >/dev/null ; then
|
||||
# Bound the total amount of output used by the ImmortalCoordinator log:
|
||||
ImmortalCoordinator $* 2>&1 | rotatelogs -f -t "$COORDLOG" 10M &
|
||||
coord_pid=$!
|
||||
if [[ ${AMBROSIA_SILENT_COORDINATOR:+defined} ]]; then
|
||||
# OPTION (1): No output from Coordinator to stdout/stderr:
|
||||
ImmortalCoordinator $* 2>&1 > "$COORDLOG" &
|
||||
coord_pid=$!
|
||||
|
||||
elif [ ${RUNAMBROSIA_USE_TAIL:+defined} ]; then
|
||||
# OPTION (2): Bound logs, but complicated (and tends to leave stray tail processes)
|
||||
# ---------------------------------------------------------------------------------
|
||||
if which rotatelogs 2> /dev/null ; then
|
||||
# Bound the total amount of output used by the ImmortalCoordinator log:
|
||||
ImmortalCoordinator $* 2>&1 | rotatelogs -f -t "$COORDLOG" 10M &
|
||||
coord_pid=$!
|
||||
else
|
||||
echo " ! WARNING $TAG: rotatelogs not available, NOT bounding size of $COORDLOG"
|
||||
ImmortalCoordinator $* >>"$COORDLOG" 2>&1 &
|
||||
coord_pid=$!
|
||||
fi
|
||||
if ! [[ ${AMBROSIA_SILENT_COORDINATOR:+defined} ]]; then
|
||||
tail_tagged "$COORDTAG" "$COORDLOG"
|
||||
fi
|
||||
else
|
||||
echo " ! WARNING $TAG: rotatelogs not available, NOT bounding size of $COORDLOG"
|
||||
ImmortalCoordinator $* >>"$COORDLOG" 2>&1 &
|
||||
coord_pid=$!
|
||||
# OPTION (3) Just use tee. Don't bound coordinator log on disk.
|
||||
# -------------------------------------------------------------
|
||||
ImmortalCoordinator $* 2>&1 | tee "$COORDLOG" | tag_stdin "$COORDTAG" &
|
||||
coord_pid=$!
|
||||
fi
|
||||
if ! [[ ${AMBROSIA_SILENT_COORDINATOR:+defined} ]]; then
|
||||
tail_tagged "$COORDTAG" "$COORDLOG"
|
||||
fi
|
||||
# ----------------------------------------
|
||||
# OPTION (2) Don't bound coordinator log on disk. Keep it simple:
|
||||
# ImmortalCoordinator $* 2>&1 | tee "$COORDLOG" &
|
||||
# coord_pid=$!
|
||||
|
||||
while ! grep -q "Ready" "$COORDLOG" && kill -0 $coord_pid 2>/dev/null ;
|
||||
do sleep 2; done
|
||||
|
||||
|
||||
if ! kill -0 $coord_pid 2>/dev/null ;
|
||||
then echo
|
||||
echo "--------------- ERROR $TAG ----------------"
|
||||
|
@ -195,7 +203,7 @@ keep_monitoring=`mktemp healthMonitorContinue.XXXXXX`
|
|||
touch $keep_monitoring
|
||||
|
||||
function monitor_health() {
|
||||
echo " $TAG Health monitor starting coord_pid=$coord_pid, app_pid=$app_pid"
|
||||
echo " $TAG Health monitor starting, coord_pid=$coord_pid, app_pid=$app_pid"
|
||||
while [ -f $keep_monitoring ]; do
|
||||
sleep 2
|
||||
if ! kill -0 $coord_pid 2>/dev/null ; then
|
||||
|
@ -220,18 +228,18 @@ start_immortal_coordinator -i $AMBROSIA_INSTANCE_NAME -p $AMBROSIA_IMMORTALCOORD
|
|||
|
||||
# Step 2:
|
||||
echo " $TAG Launching app process alongside coordinator:"
|
||||
set -x
|
||||
|
||||
# Test for interactive shell:
|
||||
if tty -s; then
|
||||
if [ -e /dev/stdin ]; then
|
||||
set -x
|
||||
$* < /dev/stdin &
|
||||
set +x
|
||||
app_pid=$!
|
||||
else
|
||||
set -x
|
||||
$* &
|
||||
set +x
|
||||
app_pid=$!
|
||||
fi
|
||||
set +x
|
||||
|
||||
|
||||
monitor_health &
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче