136 lines
4.6 KiB
C#
136 lines
4.6 KiB
C#
/*
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
All rights reserved.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
|
|
compliance with the License. You may obtain a copy of the License
|
|
at http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
|
|
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
|
|
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
|
|
|
|
See the Apache Version 2.0 License for specific language governing permissions and
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
namespace Microsoft.Research.Dryad
|
|
{
|
|
using System;
|
|
using System.ServiceModel;
|
|
using System.ServiceModel.Description;
|
|
using System.Net.Security;
|
|
|
|
class VertexCallbackServiceHost
|
|
{
|
|
private VertexCallbackService callbackService;
|
|
|
|
private ServiceHost selfHost;
|
|
|
|
public VertexCallbackServiceHost(VertexScheduler vs)
|
|
{
|
|
callbackService = new VertexCallbackService(vs);
|
|
}
|
|
|
|
public bool Start(string listenUri, ISchedulerHelper schedulerHelper)
|
|
{
|
|
DryadLogger.LogMethodEntry(listenUri);
|
|
Uri baseAddress = new Uri(listenUri);
|
|
|
|
try
|
|
{
|
|
NetTcpBinding binding = schedulerHelper.GetVertexServiceBinding();
|
|
|
|
selfHost = null;
|
|
|
|
// Retry opening the service port if address is already in use
|
|
int maxRetryCount = 20; // Results in retrying for ~1 min
|
|
for (int retryCount = 0; retryCount < maxRetryCount; retryCount++)
|
|
{
|
|
try
|
|
{
|
|
//Step 1 of the hosting procedure: Create ServiceHost
|
|
selfHost = new ServiceHost(callbackService, baseAddress);
|
|
|
|
//Step 2 of the hosting procedure: Add service endpoints.
|
|
ServiceEndpoint vertexEndpoint = selfHost.AddServiceEndpoint(typeof(IDryadVertexCallback), binding, Constants.vertexCallbackServiceName);
|
|
ServiceThrottlingBehavior stb = new ServiceThrottlingBehavior();
|
|
stb.MaxConcurrentCalls = Constants.MaxConnections;
|
|
stb.MaxConcurrentSessions = Constants.MaxConnections;
|
|
selfHost.Description.Behaviors.Add(stb);
|
|
|
|
//Step 3 of hosting procedure : Add a security manager
|
|
selfHost.Authorization.ServiceAuthorizationManager = new DryadVertexServiceAuthorizationManager();
|
|
|
|
// Step 4 of the hosting procedure: Start the service.
|
|
selfHost.Open();
|
|
break;
|
|
}
|
|
|
|
catch (AddressAlreadyInUseException)
|
|
{
|
|
if (selfHost != null)
|
|
{
|
|
selfHost.Abort();
|
|
selfHost = null;
|
|
}
|
|
|
|
// If this is the last try, dont sleep. Just rethrow exception to exit.
|
|
if (retryCount < maxRetryCount - 1)
|
|
{
|
|
DryadLogger.LogInformation("Start Vertex Callback Service", "Address already in use. Retrying...");
|
|
System.Threading.Thread.Sleep(3000);
|
|
}
|
|
else
|
|
{
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
|
|
DryadLogger.LogInformation("Start Vertex Callback Service", "Service Host started successfully");
|
|
return true;
|
|
}
|
|
catch (CommunicationException ce)
|
|
{
|
|
DryadLogger.LogCritical(0, ce, "Failed to start vertex callback service");
|
|
try
|
|
{
|
|
if (selfHost != null)
|
|
{
|
|
selfHost.Abort();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
return false;
|
|
}
|
|
}
|
|
|
|
public void Stop()
|
|
{
|
|
if (selfHost != null)
|
|
{
|
|
try
|
|
{
|
|
selfHost.Close(TimeSpan.FromMilliseconds(100));
|
|
}
|
|
catch (Exception)
|
|
{
|
|
try
|
|
{
|
|
selfHost.Abort();
|
|
}
|
|
|
|
catch { }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|