188 lines
6.8 KiB
Plaintext
188 lines
6.8 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
// File: Libraries\Resiliency\Proxy.sg
|
|
//
|
|
// Note:
|
|
//
|
|
using System;
|
|
using System.Threading;
|
|
using Microsoft.SingSharp;
|
|
using Microsoft.Singularity;
|
|
using Microsoft.Singularity.Channels;
|
|
using Microsoft.Singularity.Directory;
|
|
using Microsoft.Singularity.Services;
|
|
using Microsoft.Singularity.ServiceManager;
|
|
|
|
namespace Microsoft.Singularity.Resiliency
|
|
{
|
|
public sealed class ServiceProxy
|
|
{
|
|
private Thread serviceThread;
|
|
private JournaletFactory! factory;
|
|
private TRef<ManagedServiceContract.Exp:Ready> serviceRef;
|
|
private TRef<ManagedProxyContract.Imp:Ready> recoveryRef;
|
|
private TRef<DirectoryServiceContract.Imp:Ready> rootDsRef;
|
|
private TRef<DirectoryServiceContract.Exp:Ready> myDsRef;
|
|
private TRef<ServiceProxyContract.Exp:Ready> proxyRef;
|
|
|
|
public ServiceProxy(JournaletFactory! factory,
|
|
[Claims]ManagedServiceContract.Exp:Start! mep,
|
|
[Claims]ManagedProxyContract.Imp:Start! pep,
|
|
[Claims]DirectoryServiceContract.Imp:Ready! dep,
|
|
[Claims]DirectoryServiceContract.Exp:Start! fep,
|
|
[Claims]ServiceProxyContract.Exp:Start! xep)
|
|
{
|
|
this.factory = factory;
|
|
this.rootDsRef = new TRef<DirectoryServiceContract.Imp:Ready>(dep);
|
|
|
|
fep.SendSuccess();
|
|
this.myDsRef = new TRef<DirectoryServiceContract.Exp:Ready>(fep);
|
|
|
|
mep.SendSuccess();
|
|
this.serviceRef = new TRef<ManagedServiceContract.Exp:Ready>(mep);
|
|
|
|
switch receive {
|
|
case pep.Success():
|
|
break;
|
|
case unsatisfiable:
|
|
DebugStub.Break();
|
|
break;
|
|
}
|
|
this.recoveryRef = new TRef<ManagedProxyContract.Imp:Ready>(pep);
|
|
|
|
xep.SendSuccess();
|
|
this.proxyRef = new TRef<ServiceProxyContract.Exp:Ready>(xep);
|
|
}
|
|
|
|
public void Start()
|
|
{
|
|
if (serviceThread == null) {
|
|
serviceThread = new Thread(new ThreadStart(Run));
|
|
}
|
|
serviceThread.Start();
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
Thread thread = null;
|
|
DirectoryServiceProxy dsProxy;
|
|
ManagedServiceContract.Exp:Ready! manager;
|
|
ThreadTerminationContract.Imp! imp;
|
|
ThreadTerminationContract.Exp! exp;
|
|
|
|
DebugStub.Print("-- Start proxy\n");
|
|
|
|
dsProxy = new DirectoryServiceProxy(this,
|
|
factory,
|
|
rootDsRef.Acquire(),
|
|
myDsRef.Acquire(),
|
|
proxyRef.Acquire());
|
|
ThreadTerminationContract.NewChannel(out imp, out exp);
|
|
dsProxy.Signal(exp);
|
|
|
|
manager = serviceRef.Acquire();
|
|
for (;;) {
|
|
switch receive {
|
|
case manager.StartService():
|
|
{
|
|
if (thread == null) {
|
|
thread = new Thread(new ThreadStart(dsProxy.Run));
|
|
}
|
|
thread.Start();
|
|
manager.SendAckStartService();
|
|
break;
|
|
}
|
|
case manager.StopService():
|
|
{
|
|
DebugStub.Print("Px: recv stop service\n");
|
|
imp.SendStop();
|
|
switch receive {
|
|
case imp.AckStop():
|
|
manager.SendAckStopService();
|
|
break;
|
|
case unsatisfiable:
|
|
manager.SendBusy();
|
|
break;
|
|
}
|
|
thread = null;
|
|
break;
|
|
}
|
|
case manager.RestartService():
|
|
{
|
|
manager.SendAckRestartService();
|
|
break;
|
|
}
|
|
case manager.Knock():
|
|
{
|
|
manager.SendAlive();
|
|
break;
|
|
}
|
|
case manager.Stop():
|
|
{
|
|
imp.SendStop();
|
|
switch receive {
|
|
case unsatisfiable:
|
|
break;
|
|
}
|
|
manager.SendAckStop();
|
|
goto exit;
|
|
break;
|
|
}
|
|
case manager.Restart():
|
|
{
|
|
DebugStub.Break();
|
|
manager.SendAckRestart();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
exit:
|
|
delete manager;
|
|
delete recoveryRef.Acquire();
|
|
delete imp;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Asks ServiceManager to recover the corresponding service and
|
|
/// the initial direct channels to the service.
|
|
/// </summary>
|
|
internal void RecoverService(out DirectoryServiceContract.Exp:Ready ep,
|
|
out ServiceProxyContract.Exp:Ready xep)
|
|
{
|
|
ManagedProxyContract.Imp:Ready! manager;
|
|
DebugStub.Print("Px: Enter RecoverService\n");
|
|
|
|
manager = recoveryRef.Acquire();
|
|
#if COMPATIBLE_V1
|
|
manager.SendRequestDSRecovery();
|
|
switch receive {
|
|
case manager.AckDSRecovery(proxy):
|
|
#else
|
|
manager.SendRequestRecovery();
|
|
switch receive {
|
|
case manager.AckRecovery(directory, proxy):
|
|
#endif
|
|
{
|
|
directory.SendSuccess();
|
|
proxy.SendSuccess();
|
|
ep = directory;
|
|
xep = proxy;
|
|
break;
|
|
}
|
|
case unsatisfiable:
|
|
{
|
|
ep = null;
|
|
xep = null;
|
|
break;
|
|
}
|
|
}
|
|
recoveryRef.Release(manager);
|
|
DebugStub.Print("Px: Exit RecoverService\n");
|
|
}
|
|
}
|
|
}
|