< Summary

Information
Class: IceLocatorDiscovery.PluginI
Assembly: IceLocatorDiscovery
File(s): /_/csharp/src/IceLocatorDiscovery/PluginI.cs
Tag: 99_23991109993
Line coverage
97%
Covered lines: 48
Uncovered lines: 1
Coverable lines: 49
Total lines: 677
Line coverage: 97.9%
Branch coverage
73%
Covered branches: 22
Total branches: 30
Branch coverage: 73.3%
Method coverage
100%
Covered methods: 3
Total methods: 3
Method coverage: 100%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
initialize()75%24.012497.62%
destroy()66.67%66100%

File(s)

/_/csharp/src/IceLocatorDiscovery/PluginI.cs

#LineLine coverage
 1// Copyright (c) ZeroC, Inc.
 2
 3using System.Diagnostics;
 4using System.Text;
 5
 6namespace IceLocatorDiscovery;
 7
 8public sealed class PluginFactory : Ice.PluginFactory
 9{
 10    public string pluginName => "IceLocatorDiscovery";
 11
 12    public Ice.Plugin create(Ice.Communicator communicator, string name, string[] args)
 13    {
 14        if (name != pluginName)
 15        {
 16            throw new Ice.PluginInitializationException(
 17                $"The Locator Discovery plug-in must be named '{pluginName}'.");
 18        }
 19
 20        return new PluginI(communicator);
 21    }
 22}
 23
 24internal class Request : TaskCompletionSource<Ice.Object_Ice_invokeResult>
 25{
 26    public Request(
 27        LocatorI locator,
 28        string operation,
 29        Ice.OperationMode mode,
 30        byte[] inParams,
 31        Dictionary<string, string> context)
 32        : base(TaskCreationOptions.RunContinuationsAsynchronously)
 33    {
 34        _locator = locator;
 35        _operation = operation;
 36        _mode = mode;
 37        _inParams = inParams;
 38        _context = context;
 39    }
 40
 41    public void
 42    invoke(Ice.LocatorPrx l)
 43    {
 44        if (_locatorPrx == null || !_locatorPrx.Equals(l))
 45        {
 46            _locatorPrx = l;
 47            _ = performInvokeAsync(l);
 48        }
 49        else
 50        {
 51            Debug.Assert(_exception != null);
 52            throw _exception;
 53        }
 54
 55        async Task performInvokeAsync(Ice.LocatorPrx locator)
 56        {
 57            try
 58            {
 59                Ice.Object_Ice_invokeResult result =
 60                    await locator.ice_invokeAsync(_operation, _mode, _inParams, _context).ConfigureAwait(false);
 61                SetResult(result);
 62            }
 63            catch (Ice.RequestFailedException exc)
 64            {
 65                SetException(exc);
 66            }
 67            catch (Ice.UnknownException exc)
 68            {
 69                SetException(exc);
 70            }
 71            catch (Ice.NoEndpointException)
 72            {
 73                SetException(new Ice.ObjectNotExistException());
 74            }
 75            catch (Ice.ObjectAdapterDeactivatedException)
 76            {
 77                SetException(new Ice.ObjectNotExistException());
 78            }
 79            catch (Ice.ObjectAdapterDestroyedException)
 80            {
 81                SetException(new Ice.ObjectNotExistException());
 82            }
 83            catch (Ice.CommunicatorDestroyedException)
 84            {
 85                SetException(new Ice.ObjectNotExistException());
 86            }
 87            catch (Exception exc)
 88            {
 89                _exception = exc;
 90                _locator.invoke(_locatorPrx, this); // Retry with new locator proxy
 91            }
 92        }
 93    }
 94
 95    private readonly LocatorI _locator;
 96    private readonly string _operation;
 97    private readonly Ice.OperationMode _mode;
 98    private readonly Dictionary<string, string> _context;
 99    private readonly byte[] _inParams;
 100
 101    private Ice.LocatorPrx _locatorPrx;
 102    private Exception _exception;
 103}
 104
 105internal class VoidLocatorI : Ice.LocatorDisp_
 106{
 107    public override Ice.ObjectPrx findObjectById(Ice.Identity id, Ice.Current current) => null;
 108
 109    public override Ice.ObjectPrx findAdapterById(string id, Ice.Current current) => null;
 110
 111    public override Ice.LocatorRegistryPrx getRegistry(Ice.Current current) => null;
 112}
 113
 114internal class LocatorI : Ice.BlobjectAsync, Ice.Internal.TimerTask
 115{
 116    public
 117    LocatorI(LookupPrx lookup, Ice.Properties properties, string instanceName, Ice.LocatorPrx voidLocator)
 118    {
 119        _lookup = lookup;
 120        _timeout = properties.getIcePropertyAsInt("IceLocatorDiscovery.Timeout");
 121        if (_timeout < 0)
 122        {
 123            _timeout = 300;
 124        }
 125        _retryCount = properties.getIcePropertyAsInt("IceLocatorDiscovery.RetryCount");
 126        if (_retryCount < 0)
 127        {
 128            _retryCount = 0;
 129        }
 130        _retryDelay = properties.getIcePropertyAsInt("IceLocatorDiscovery.RetryDelay");
 131        if (_retryDelay < 0)
 132        {
 133            _retryDelay = 0;
 134        }
 135        _timer = Ice.Internal.Util.getInstance(lookup.ice_getCommunicator()).timer();
 136        _traceLevel = properties.getIcePropertyAsInt("IceLocatorDiscovery.Trace.Lookup");
 137        _instanceName = instanceName;
 138        _warned = false;
 139        _locator = lookup.ice_getCommunicator().getDefaultLocator();
 140        _voidLocator = voidLocator;
 141        _pending = false;
 142        _pendingRetryCount = 0;
 143        _failureCount = 0;
 144        _warnOnce = true;
 145
 146        //
 147        // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
 148        // datagram on each endpoint.
 149        //
 150        var single = new Ice.Endpoint[1];
 151        foreach (Ice.Endpoint endpoint in lookup.ice_getEndpoints())
 152        {
 153            single[0] = endpoint;
 154            _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null;
 155        }
 156        Debug.Assert(_lookups.Count > 0);
 157    }
 158
 159    public void
 160    setLookupReply(LookupReplyPrx lookupReply)
 161    {
 162        //
 163        // Use a lookup reply proxy whose address matches the interface used to send multicast datagrams.
 164        //
 165        var single = new Ice.Endpoint[1];
 166        foreach (LookupPrx key in new List<LookupPrx>(_lookups.Keys))
 167        {
 168            var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
 169            if (info.mcastInterface.Length > 0)
 170            {
 171                foreach (Ice.Endpoint q in lookupReply.ice_getEndpoints())
 172                {
 173                    Ice.EndpointInfo r = q.getInfo();
 174                    if (r is Ice.IPEndpointInfo &&
 175                        ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface, StringComparison.Ordinal))
 176                    {
 177                        single[0] = q;
 178                        _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
 179                        break;
 180                    }
 181                }
 182            }
 183
 184            if (_lookups[key] == null)
 185            {
 186                // Fallback: just use the given lookup reply proxy if no matching endpoint found.
 187                _lookups[key] = lookupReply;
 188            }
 189        }
 190    }
 191
 192    public override Task<Ice.Object_Ice_invokeResult>
 193    ice_invokeAsync(byte[] inParams, Ice.Current current)
 194    {
 195        lock (_mutex)
 196        {
 197            var request = new Request(this, current.operation, current.mode, inParams, current.ctx);
 198            invoke(null, request);
 199            return request.Task;
 200        }
 201    }
 202
 203    public void
 204    foundLocator(Ice.LocatorPrx locator)
 205    {
 206        lock (_mutex)
 207        {
 208            if (_instanceName.Length > 0 &&
 209                !locator.ice_getIdentity().category.Equals(_instanceName, StringComparison.Ordinal))
 210            {
 211                if (_traceLevel > 2)
 212                {
 213                    var s = new StringBuilder("ignoring locator reply: instance name doesn't match\n");
 214                    s.Append("expected = ").Append(_instanceName);
 215                    s.Append("received = ").Append(locator.ice_getIdentity().category);
 216                    _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 217                }
 218                return;
 219            }
 220
 221            //
 222            // If we already have a locator assigned, ensure the given locator
 223            // has the same identity, otherwise ignore it.
 224            //
 225            if (_pendingRequests.Count > 0 &&
 226               _locator != null &&
 227               !locator.ice_getIdentity().category.Equals(
 228                   _locator.ice_getIdentity().category,
 229                   StringComparison.Ordinal))
 230            {
 231                if (!_warned)
 232                {
 233                    _warned = true; // Only warn once
 234
 235                    locator.ice_getCommunicator().getLogger().warning(
 236                    "received Ice locator with different instance name:\n" +
 237                    "using = `" + _locator.ice_getIdentity().category + "'\n" +
 238                    "received = `" + locator.ice_getIdentity().category + "'\n" +
 239                    "This is typically the case if multiple Ice locators with different " +
 240                    "instance names are deployed and the property `IceLocatorDiscovery.InstanceName'" +
 241                    "is not set.");
 242                }
 243                return;
 244            }
 245
 246            if (_pending) // No need to continue, we found a locator
 247            {
 248                _timer.cancel(this);
 249                _pendingRetryCount = 0;
 250                _pending = false;
 251            }
 252
 253            if (_traceLevel > 0)
 254            {
 255                var s = new StringBuilder("locator lookup succeeded:\nlocator = ");
 256                s.Append(locator);
 257                if (_instanceName.Length > 0)
 258                {
 259                    s.Append("\ninstance name = ").Append(_instanceName);
 260                }
 261                _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 262            }
 263
 264            Ice.LocatorPrx l = null;
 265            if (_pendingRequests.Count == 0)
 266            {
 267                _locators.TryGetValue(locator.ice_getIdentity().category, out _locator);
 268            }
 269            else
 270            {
 271                l = _locator;
 272            }
 273            if (l != null)
 274            {
 275                //
 276                // We found another locator replica, append its endpoints to the
 277                // current locator proxy endpoints.
 278                //
 279                var newEndpoints = new List<Ice.Endpoint>(l.ice_getEndpoints());
 280                foreach (Ice.Endpoint p in locator.ice_getEndpoints())
 281                {
 282                    //
 283                    // Only add endpoints if not already in the locator proxy endpoints
 284                    //
 285                    bool found = false;
 286                    foreach (Ice.Endpoint q in newEndpoints)
 287                    {
 288                        if (p.Equals(q))
 289                        {
 290                            found = true;
 291                            break;
 292                        }
 293                    }
 294                    if (!found)
 295                    {
 296                        newEndpoints.Add(p);
 297                    }
 298                }
 299                l = (Ice.LocatorPrx)l.ice_endpoints(newEndpoints.ToArray());
 300            }
 301            else
 302            {
 303                l = locator;
 304            }
 305
 306            if (_pendingRequests.Count == 0)
 307            {
 308                _locators[locator.ice_getIdentity().category] = l;
 309            }
 310            else
 311            {
 312                _locator = l;
 313                if (_instanceName.Length == 0)
 314                {
 315                    _instanceName = _locator.ice_getIdentity().category; // Stick to the first locator
 316                }
 317
 318                //
 319                // Send pending requests if any.
 320                //
 321                foreach (Request req in _pendingRequests)
 322                {
 323                    req.invoke(_locator);
 324                }
 325                _pendingRequests.Clear();
 326            }
 327        }
 328    }
 329
 330    public void
 331    invoke(Ice.LocatorPrx locator, Request request)
 332    {
 333        lock (_mutex)
 334        {
 335            if (request != null && _locator != null && _locator != locator)
 336            {
 337                request.invoke(_locator);
 338            }
 339            else if (request != null && Ice.Internal.Time.currentMonotonicTimeMillis() < _nextRetry)
 340            {
 341                request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
 342            }
 343            else
 344            {
 345                _locator = null;
 346
 347                if (request != null)
 348                {
 349                    _pendingRequests.Add(request);
 350                }
 351
 352                if (!_pending) // No request in progress
 353                {
 354                    _pending = true;
 355                    _pendingRetryCount = _retryCount;
 356                    _failureCount = 0;
 357                    try
 358                    {
 359                        if (_traceLevel > 1)
 360                        {
 361                            var s = new StringBuilder("looking up locator:\nlookup = ");
 362                            s.Append(_lookup);
 363                            if (_instanceName.Length > 0)
 364                            {
 365                                s.Append("\ninstance name = ").Append(_instanceName);
 366                            }
 367                            _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 368                        }
 369
 370                        foreach (KeyValuePair<LookupPrx, LookupReplyPrx> l in _lookups)
 371                        {
 372                            _ = performFindLocatorAsync(l.Key, l.Value);
 373                        }
 374                        _timer.schedule(this, _timeout);
 375                    }
 376                    catch (Ice.LocalException ex)
 377                    {
 378                        if (_traceLevel > 0)
 379                        {
 380                            var s = new StringBuilder("locator lookup failed:\nlookup = ");
 381                            s.Append(_lookup);
 382                            if (_instanceName.Length > 0)
 383                            {
 384                                s.Append("\ninstance name = ").Append(_instanceName);
 385                            }
 386                            s.Append('\n').Append(ex);
 387                            _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 388                        }
 389
 390                        foreach (Request req in _pendingRequests)
 391                        {
 392                            req.invoke(_voidLocator);
 393                        }
 394                        _pendingRequests.Clear();
 395                        _pendingRetryCount = 0;
 396                        _pending = false;
 397                    }
 398                }
 399            }
 400        }
 401
 402        async Task performFindLocatorAsync(LookupPrx lookupPrx, LookupReplyPrx lookupReplyPrx)
 403        {
 404            // Exit the mutex lock before proceeding.
 405            await Task.Yield();
 406
 407            // Send multicast request.
 408            try
 409            {
 410                await lookupPrx.findLocatorAsync(_instanceName, lookupReplyPrx).ConfigureAwait(false);
 411            }
 412            catch (System.Exception ex)
 413            {
 414                exception(ex);
 415            }
 416        }
 417    }
 418
 419    private void exception(Exception ex)
 420    {
 421        lock (_mutex)
 422        {
 423            if (++_failureCount == _lookups.Count && _pending)
 424            {
 425                //
 426                // All the lookup calls failed, cancel the timer and propagate the error to the requests.
 427                //
 428                _timer.cancel(this);
 429                _pendingRetryCount = 0;
 430                _pending = false;
 431
 432                if (_warnOnce)
 433                {
 434                    var builder = new StringBuilder();
 435                    builder.Append("failed to lookup locator with lookup proxy `");
 436                    builder.Append(_lookup);
 437                    builder.Append("':\n");
 438                    builder.Append(ex);
 439                    _lookup.ice_getCommunicator().getLogger().warning(builder.ToString());
 440                    _warnOnce = false;
 441                }
 442
 443                if (_traceLevel > 0)
 444                {
 445                    var s = new StringBuilder("locator lookup failed:\nlookup = ");
 446                    s.Append(_lookup);
 447                    if (_instanceName.Length > 0)
 448                    {
 449                        s.Append("\ninstance name = ").Append(_instanceName);
 450                    }
 451                    s.Append('\n').Append(ex);
 452                    _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 453                }
 454
 455                if (_pendingRequests.Count > 0)
 456                {
 457                    foreach (Request req in _pendingRequests)
 458                    {
 459                        req.invoke(_voidLocator);
 460                    }
 461                    _pendingRequests.Clear();
 462                }
 463            }
 464        }
 465    }
 466
 467    public void runTimerTask()
 468    {
 469        lock (_mutex)
 470        {
 471            if (!_pending)
 472            {
 473                Debug.Assert(_pendingRequests.Count == 0);
 474                return; // Request failed
 475            }
 476
 477            if (_pendingRetryCount > 0)
 478            {
 479                --_pendingRetryCount;
 480                try
 481                {
 482                    if (_traceLevel > 1)
 483                    {
 484                        var s = new StringBuilder("retrying locator lookup:\nlookup = ");
 485                        s.Append(_lookup);
 486                        s.Append("\nretry count = ").Append(_retryCount);
 487                        if (_instanceName.Length > 0)
 488                        {
 489                            s.Append("\ninstance name = ").Append(_instanceName);
 490                        }
 491                        _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 492                    }
 493
 494                    foreach (KeyValuePair<LookupPrx, LookupReplyPrx> l in _lookups)
 495                    {
 496                        l.Key.findLocatorAsync(_instanceName, l.Value).ContinueWith(
 497                            t =>
 498                            {
 499                                try
 500                                {
 501                                    t.Wait();
 502                                }
 503                                catch (AggregateException ex)
 504                                {
 505                                    exception(ex.InnerException);
 506                                }
 507                            },
 508                            l.Key.ice_scheduler()); // Send multicast request.
 509                    }
 510                    _timer.schedule(this, _timeout);
 511                    return;
 512                }
 513                catch (Ice.LocalException)
 514                {
 515                }
 516                _pendingRetryCount = 0;
 517            }
 518
 519            Debug.Assert(_pendingRetryCount == 0);
 520            _pending = false;
 521
 522            if (_traceLevel > 0)
 523            {
 524                var s = new StringBuilder("locator lookup timed out:\nlookup = ");
 525                s.Append(_lookup);
 526                if (_instanceName.Length > 0)
 527                {
 528                    s.Append("\ninstance name = ").Append(_instanceName);
 529                }
 530                _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 531            }
 532
 533            if (_pendingRequests.Count > 0)
 534            {
 535                foreach (Request req in _pendingRequests)
 536                {
 537                    req.invoke(_voidLocator);
 538                }
 539                _pendingRequests.Clear();
 540            }
 541            _nextRetry = Ice.Internal.Time.currentMonotonicTimeMillis() + _retryDelay;
 542        }
 543    }
 544
 545    private readonly LookupPrx _lookup;
 546    private readonly Dictionary<LookupPrx, LookupReplyPrx> _lookups = new Dictionary<LookupPrx, LookupReplyPrx>();
 547    private readonly int _timeout;
 548    private readonly Ice.Internal.Timer _timer;
 549    private readonly int _traceLevel;
 550    private readonly int _retryCount;
 551    private readonly int _retryDelay;
 552
 553    private string _instanceName;
 554    private bool _warned;
 555    private Ice.LocatorPrx _locator;
 556    private readonly Ice.LocatorPrx _voidLocator;
 557    private readonly Dictionary<string, Ice.LocatorPrx> _locators = new Dictionary<string, Ice.LocatorPrx>();
 558
 559    private bool _pending;
 560    private int _pendingRetryCount;
 561    private int _failureCount;
 562    private bool _warnOnce = true;
 563    private readonly List<Request> _pendingRequests = new List<Request>();
 564    private long _nextRetry;
 565    private readonly object _mutex = new();
 566}
 567
 568internal class LookupReplyI : LookupReplyDisp_
 569{
 570    public LookupReplyI(LocatorI locator) => _locator = locator;
 571
 572    public override void
 573    foundLocator(Ice.LocatorPrx locator, Ice.Current current)
 574    {
 575        Ice.ObjectPrx.checkNotNull(locator, current);
 576        _locator.foundLocator(locator);
 577    }
 578
 579    private readonly LocatorI _locator;
 580}
 581
 582internal class PluginI : Ice.Plugin
 583{
 1584    public
 1585    PluginI(Ice.Communicator communicator) => _communicator = communicator;
 586
 587    public void
 588    initialize()
 589    {
 1590        Ice.Properties properties = _communicator.getProperties();
 591
 1592        bool ipv4 = properties.getIcePropertyAsInt("Ice.IPv4") > 0;
 1593        bool preferIPv6 = properties.getIcePropertyAsInt("Ice.PreferIPv6Address") > 0;
 1594        string address = properties.getIceProperty("IceLocatorDiscovery.Address");
 1595        if (address.Length == 0)
 596        {
 1597            address = ipv4 && !preferIPv6 ? "239.255.0.1" : "ff15::1";
 598        }
 1599        int port = properties.getIcePropertyAsInt("IceLocatorDiscovery.Port");
 1600        string intf = properties.getIceProperty("IceLocatorDiscovery.Interface");
 601
 1602        string lookupEndpoints = properties.getIceProperty("IceLocatorDiscovery.Lookup");
 1603        if (lookupEndpoints.Length == 0)
 604        {
 1605            int protocol = ipv4 && !preferIPv6 ? Ice.Internal.Network.EnableIPv4 : Ice.Internal.Network.EnableIPv6;
 1606            List<string> interfaces = Ice.Internal.Network.getInterfacesForMulticast(intf, protocol);
 1607            foreach (string p in interfaces)
 608            {
 1609                if (p != interfaces[0])
 610                {
 0611                    lookupEndpoints += ":";
 612                }
 1613                lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
 614            }
 615        }
 616
 1617        if (properties.getIceProperty("IceLocatorDiscovery.Reply.Endpoints").Length == 0)
 618        {
 1619            properties.setProperty(
 1620                "IceLocatorDiscovery.Reply.Endpoints",
 1621                "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\""));
 622        }
 623
 1624        if (properties.getIceProperty("IceLocatorDiscovery.Locator.Endpoints").Length == 0)
 625        {
 1626            properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", Guid.NewGuid().ToString());
 627        }
 628
 1629        _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply");
 1630        _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator");
 631
 632        // We don't want those adapters to be registered with the locator so clear their locator.
 1633        _replyAdapter.setLocator(null);
 1634        _locatorAdapter.setLocator(null);
 635
 1636        Ice.ObjectPrx lookupPrx = Ice.ObjectPrxHelper.createProxy(
 1637            _communicator,
 1638            "IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
 639
 1640        lookupPrx = lookupPrx.ice_router(null);
 641
 1642        Ice.LocatorPrx voidLo = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI()));
 643
 1644        string instanceName = properties.getIceProperty("IceLocatorDiscovery.InstanceName");
 1645        var id = new Ice.Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString());
 646
 1647        _defaultLocator = _communicator.getDefaultLocator();
 1648        _locator = new LocatorI(LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo);
 1649        _locatorPrx = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.add(_locator, id));
 1650        _communicator.setDefaultLocator(_locatorPrx);
 651
 1652        Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram();
 1653        _locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
 654
 1655        _replyAdapter.activate();
 1656        _locatorAdapter.activate();
 1657    }
 658
 659    public void
 660    destroy()
 661    {
 1662        _replyAdapter?.destroy();
 1663        _locatorAdapter?.destroy();
 1664        if (_communicator.getDefaultLocator().Equals(_locatorPrx))
 665        {
 666            // Restore original default locator proxy, if the user didn't change it in the meantime
 1667            _communicator.setDefaultLocator(_defaultLocator);
 668        }
 1669    }
 670
 671    private readonly Ice.Communicator _communicator;
 672    private Ice.ObjectAdapter _locatorAdapter;
 673    private Ice.ObjectAdapter _replyAdapter;
 674    private LocatorI _locator;
 675    private Ice.LocatorPrx _locatorPrx;
 676    private Ice.LocatorPrx _defaultLocator;
 677}