< Summary

Information
Class: IceLocatorDiscovery.Request
Assembly: IceLocatorDiscovery
File(s): /_/csharp/src/IceLocatorDiscovery/PluginI.cs
Tag: 125_37167941578
Line coverage
74%
Covered lines: 20
Uncovered lines: 7
Coverable lines: 27
Total lines: 691
Line coverage: 74%
Branch coverage
25%
Covered branches: 1
Total branches: 4
Branch coverage: 25%
Method coverage
100%
Covered methods: 4
Fully covered methods: 2
Total methods: 4
Method coverage: 100%
Full method coverage: 50%

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
invoke(...)25%5460%
performInvokeAsync()100%11100%
handleException(...)100%1128.57%

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)
 132        : base(TaskCreationOptions.RunContinuationsAsynchronously)
 33    {
 134        _locator = locator;
 135        _operation = operation;
 136        _mode = mode;
 137        _inParams = inParams;
 138        _context = context;
 139    }
 40
 41    public void
 42    invoke(Ice.LocatorPrx l)
 43    {
 144        if (_locatorPrx == null || !_locatorPrx.Equals(l))
 45        {
 146            _locatorPrx = l;
 147            _ = performInvokeAsync(l);
 48        }
 49        else
 50        {
 51            Debug.Assert(_exception != null); // Don't retry if the proxy didn't change
 052            SetException(_exception); // Complete the request directly, matching the C++ mapping
 53        }
 54
 55        async Task performInvokeAsync(Ice.LocatorPrx locator)
 56        {
 57            try
 58            {
 159                Ice.Object_Ice_invokeResult result =
 160                    await locator.ice_invokeAsync(_operation, _mode, _inParams, _context).ConfigureAwait(false);
 161                SetResult(result);
 162            }
 163            catch (System.Exception exc)
 64            {
 165                handleException(exc);
 166            }
 167        }
 068    }
 69
 70    private void handleException(System.Exception exc)
 71    {
 72        switch (exc)
 73        {
 74            case Ice.RequestFailedException:
 75            case Ice.UnknownException:
 176                SetException(exc);
 177                break;
 78            case Ice.NoEndpointException:
 79            case Ice.ObjectAdapterDeactivatedException:
 80            case Ice.ObjectAdapterDestroyedException:
 81            case Ice.CommunicatorDestroyedException:
 082                SetException(new Ice.ObjectNotExistException());
 083                break;
 84            default:
 085                _exception = exc;
 086                _locator.invoke(_locatorPrx, this); // Retry with new locator proxy
 87                break;
 88        }
 089    }
 90
 91    private readonly LocatorI _locator;
 92    private readonly string _operation;
 93    private readonly Ice.OperationMode _mode;
 94    private readonly Dictionary<string, string> _context;
 95    private readonly byte[] _inParams;
 96
 97    private Ice.LocatorPrx _locatorPrx;
 98    private Exception _exception;
 99}
 100
 101internal class VoidLocatorI : Ice.LocatorDisp_
 102{
 103    public override Ice.ObjectPrx findObjectById(Ice.Identity id, Ice.Current current) => null;
 104
 105    public override Ice.ObjectPrx findAdapterById(string id, Ice.Current current) => null;
 106
 107    public override Ice.LocatorRegistryPrx getRegistry(Ice.Current current) => null;
 108}
 109
 110internal class LocatorI : Ice.BlobjectAsync, Ice.Internal.TimerTask
 111{
 112    public
 113    LocatorI(LookupPrx lookup, Ice.Properties properties, string instanceName, Ice.LocatorPrx voidLocator)
 114    {
 115        _lookup = lookup;
 116        _timeout = TimeSpan.FromMilliseconds(properties.getIcePropertyAsInt("IceLocatorDiscovery.Timeout"));
 117        if (_timeout <= TimeSpan.Zero)
 118        {
 119            throw new Ice.PropertyException("property 'IceLocatorDiscovery.Timeout' must be greater than 0");
 120        }
 121        _retryCount = properties.getIcePropertyAsInt("IceLocatorDiscovery.RetryCount");
 122        if (_retryCount < 0)
 123        {
 124            throw new Ice.PropertyException(
 125                "property 'IceLocatorDiscovery.RetryCount' must be greater than or equal to 0");
 126        }
 127        _retryDelay = properties.getIcePropertyAsInt("IceLocatorDiscovery.RetryDelay");
 128        if (_retryDelay < 0)
 129        {
 130            throw new Ice.PropertyException(
 131                "property 'IceLocatorDiscovery.RetryDelay' must be greater than or equal to 0");
 132        }
 133        _timer = Ice.Internal.Util.getInstance(lookup.ice_getCommunicator()).timer();
 134        _traceLevel = properties.getIcePropertyAsInt("IceLocatorDiscovery.Trace.Lookup");
 135        _instanceName = instanceName;
 136        _warned = false;
 137        _locator = lookup.ice_getCommunicator().getDefaultLocator();
 138        _voidLocator = voidLocator;
 139        _pending = false;
 140        _pendingRetryCount = 0;
 141        _failureCount = 0;
 142        _warnOnce = true;
 143
 144        //
 145        // Create one lookup proxy per endpoint from the given proxy. We want to send a multicast
 146        // datagram on each endpoint.
 147        //
 148        var single = new Ice.Endpoint[1];
 149        foreach (Ice.Endpoint endpoint in lookup.ice_getEndpoints())
 150        {
 151            single[0] = endpoint;
 152            _lookups[(LookupPrx)lookup.ice_endpoints(single)] = null;
 153        }
 154        Debug.Assert(_lookups.Count > 0);
 155    }
 156
 157    public void
 158    setLookupReply(LookupReplyPrx lookupReply)
 159    {
 160        //
 161        // Use a lookup reply proxy whose address matches the interface used to send multicast datagrams.
 162        //
 163        var single = new Ice.Endpoint[1];
 164        foreach (LookupPrx key in new List<LookupPrx>(_lookups.Keys))
 165        {
 166            var info = (Ice.UDPEndpointInfo)key.ice_getEndpoints()[0].getInfo();
 167            if (info.mcastInterface.Length > 0)
 168            {
 169                foreach (Ice.Endpoint q in lookupReply.ice_getEndpoints())
 170                {
 171                    Ice.EndpointInfo r = q.getInfo();
 172                    if (r is Ice.IPEndpointInfo &&
 173                        ((Ice.IPEndpointInfo)r).host.Equals(info.mcastInterface, StringComparison.Ordinal))
 174                    {
 175                        single[0] = q;
 176                        _lookups[key] = (LookupReplyPrx)lookupReply.ice_endpoints(single);
 177                        break;
 178                    }
 179                }
 180            }
 181
 182            if (_lookups[key] == null)
 183            {
 184                // Fallback: just use the given lookup reply proxy if no matching endpoint found.
 185                _lookups[key] = lookupReply;
 186            }
 187        }
 188    }
 189
 190    public override Task<Ice.Object_Ice_invokeResult>
 191    ice_invokeAsync(byte[] inParams, Ice.Current current)
 192    {
 193        lock (_mutex)
 194        {
 195            var request = new Request(this, current.operation, current.mode, inParams, current.ctx);
 196            invoke(null, request);
 197            return request.Task;
 198        }
 199    }
 200
 201    public void
 202    foundLocator(Ice.LocatorPrx locator)
 203    {
 204        lock (_mutex)
 205        {
 206            if (_instanceName.Length > 0 &&
 207                !locator.ice_getIdentity().category.Equals(_instanceName, StringComparison.Ordinal))
 208            {
 209                if (_traceLevel > 2)
 210                {
 211                    var s = new StringBuilder("ignoring locator reply: instance name doesn't match\n");
 212                    s.Append("expected = ").Append(_instanceName);
 213                    s.Append("received = ").Append(locator.ice_getIdentity().category);
 214                    _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 215                }
 216                return;
 217            }
 218
 219            //
 220            // If we already have a locator assigned, ensure the given locator
 221            // has the same identity, otherwise ignore it.
 222            //
 223            if (_pendingRequests.Count > 0 &&
 224               _locator != null &&
 225               !locator.ice_getIdentity().category.Equals(
 226                   _locator.ice_getIdentity().category,
 227                   StringComparison.Ordinal))
 228            {
 229                if (!_warned)
 230                {
 231                    _warned = true; // Only warn once
 232
 233                    locator.ice_getCommunicator().getLogger().warning(
 234                    "received Ice locator with different instance name:\n" +
 235                    "using = `" + _locator.ice_getIdentity().category + "'\n" +
 236                    "received = `" + locator.ice_getIdentity().category + "'\n" +
 237                    "This is typically the case if multiple Ice locators with different " +
 238                    "instance names are deployed and the property `IceLocatorDiscovery.InstanceName' " +
 239                    "is not set.");
 240                }
 241                return;
 242            }
 243
 244            if (_pending) // No need to continue, we found a locator
 245            {
 246                _timer.cancel(this);
 247                _pendingRetryCount = 0;
 248                _pending = false;
 249            }
 250
 251            if (_traceLevel > 0)
 252            {
 253                var s = new StringBuilder("locator lookup succeeded:\nlocator = ");
 254                s.Append(locator);
 255                if (_instanceName.Length > 0)
 256                {
 257                    s.Append("\ninstance name = ").Append(_instanceName);
 258                }
 259                _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 260            }
 261
 262            Ice.LocatorPrx l = null;
 263            if (_pendingRequests.Count == 0)
 264            {
 265                _locators.TryGetValue(locator.ice_getIdentity().category, out _locator);
 266            }
 267            else
 268            {
 269                l = _locator;
 270            }
 271            if (l != null)
 272            {
 273                //
 274                // We found another locator replica, append its endpoints to the
 275                // current locator proxy endpoints.
 276                //
 277                var newEndpoints = new List<Ice.Endpoint>(l.ice_getEndpoints());
 278                foreach (Ice.Endpoint p in locator.ice_getEndpoints())
 279                {
 280                    //
 281                    // Only add endpoints if not already in the locator proxy endpoints
 282                    //
 283                    bool found = false;
 284                    foreach (Ice.Endpoint q in newEndpoints)
 285                    {
 286                        if (p.Equals(q))
 287                        {
 288                            found = true;
 289                            break;
 290                        }
 291                    }
 292                    if (!found)
 293                    {
 294                        newEndpoints.Add(p);
 295                    }
 296                }
 297                l = (Ice.LocatorPrx)l.ice_endpoints(newEndpoints.ToArray());
 298            }
 299            else
 300            {
 301                l = locator;
 302            }
 303
 304            if (_pendingRequests.Count == 0)
 305            {
 306                _locators[locator.ice_getIdentity().category] = l;
 307            }
 308            else
 309            {
 310                _locator = l;
 311                if (_instanceName.Length == 0)
 312                {
 313                    _instanceName = _locator.ice_getIdentity().category; // Stick to the first locator
 314                }
 315
 316                //
 317                // Send pending requests if any.
 318                //
 319                foreach (Request req in _pendingRequests)
 320                {
 321                    req.invoke(_locator);
 322                }
 323                _pendingRequests.Clear();
 324            }
 325        }
 326    }
 327
 328    public void
 329    invoke(Ice.LocatorPrx locator, Request request)
 330    {
 331        lock (_mutex)
 332        {
 333            if (request != null && _locator != null && _locator != locator)
 334            {
 335                request.invoke(_locator);
 336            }
 337            else if (request != null && Ice.Internal.Time.currentMonotonicTimeMillis() < _nextRetry)
 338            {
 339                request.invoke(_voidLocator); // Don't retry to find a locator before the retry delay expires
 340            }
 341            else
 342            {
 343                _locator = null;
 344
 345                if (request != null)
 346                {
 347                    _pendingRequests.Add(request);
 348                }
 349
 350                if (!_pending) // No request in progress
 351                {
 352                    _pending = true;
 353                    _pendingRetryCount = _retryCount;
 354                    _failureCount = 0;
 355                    ++_generation;
 356                    try
 357                    {
 358                        if (_traceLevel > 1)
 359                        {
 360                            var s = new StringBuilder("looking up locator:\nlookup = ");
 361                            s.Append(_lookup);
 362                            if (_instanceName.Length > 0)
 363                            {
 364                                s.Append("\ninstance name = ").Append(_instanceName);
 365                            }
 366                            _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 367                        }
 368
 369                        foreach (KeyValuePair<LookupPrx, LookupReplyPrx> l in _lookups)
 370                        {
 371                            _ = performFindLocatorAsync(l.Key, l.Value, _generation);
 372                        }
 373                        _timer.schedule(this, _timeout);
 374                    }
 375                    catch (Ice.LocalException ex)
 376                    {
 377                        if (_traceLevel > 0)
 378                        {
 379                            var s = new StringBuilder("locator lookup failed:\nlookup = ");
 380                            s.Append(_lookup);
 381                            if (_instanceName.Length > 0)
 382                            {
 383                                s.Append("\ninstance name = ").Append(_instanceName);
 384                            }
 385                            s.Append('\n').Append(ex);
 386                            _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 387                        }
 388
 389                        foreach (Request req in _pendingRequests)
 390                        {
 391                            req.invoke(_voidLocator);
 392                        }
 393                        _pendingRequests.Clear();
 394                        _pendingRetryCount = 0;
 395                        _pending = false;
 396                    }
 397                }
 398            }
 399        }
 400
 401        async Task performFindLocatorAsync(LookupPrx lookupPrx, LookupReplyPrx lookupReplyPrx, int generation)
 402        {
 403            // Exit the mutex lock before proceeding.
 404            await Task.Yield();
 405
 406            // Send multicast request.
 407            try
 408            {
 409                await lookupPrx.findLocatorAsync(_instanceName, lookupReplyPrx).ConfigureAwait(false);
 410            }
 411            catch (System.Exception ex)
 412            {
 413                exception(ex, generation);
 414            }
 415        }
 416    }
 417
 418    private void exception(Exception ex, int generation)
 419    {
 420        lock (_mutex)
 421        {
 422            // Ignore a delayed failure from an earlier lookup round: it must not count against the current round, which
 423            // reset _failureCount and may still have outstanding lookups.
 424            if (generation != _generation)
 425            {
 426                return;
 427            }
 428            if (++_failureCount == _lookups.Count && _pending)
 429            {
 430                //
 431                // All the lookup calls failed, cancel the timer and propagate the error to the requests.
 432                //
 433                _timer.cancel(this);
 434                _pendingRetryCount = 0;
 435                _pending = false;
 436
 437                if (_warnOnce)
 438                {
 439                    var builder = new StringBuilder();
 440                    builder.Append("failed to lookup locator with lookup proxy `");
 441                    builder.Append(_lookup);
 442                    builder.Append("':\n");
 443                    builder.Append(ex);
 444                    _lookup.ice_getCommunicator().getLogger().warning(builder.ToString());
 445                    _warnOnce = false;
 446                }
 447
 448                if (_traceLevel > 0)
 449                {
 450                    var s = new StringBuilder("locator lookup failed:\nlookup = ");
 451                    s.Append(_lookup);
 452                    if (_instanceName.Length > 0)
 453                    {
 454                        s.Append("\ninstance name = ").Append(_instanceName);
 455                    }
 456                    s.Append('\n').Append(ex);
 457                    _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 458                }
 459
 460                if (_pendingRequests.Count > 0)
 461                {
 462                    foreach (Request req in _pendingRequests)
 463                    {
 464                        req.invoke(_voidLocator);
 465                    }
 466                    _pendingRequests.Clear();
 467                }
 468            }
 469        }
 470    }
 471
 472    public void runTimerTask()
 473    {
 474        lock (_mutex)
 475        {
 476            if (!_pending)
 477            {
 478                Debug.Assert(_pendingRequests.Count == 0);
 479                return; // Request failed
 480            }
 481
 482            if (_pendingRetryCount > 0)
 483            {
 484                --_pendingRetryCount;
 485                try
 486                {
 487                    if (_traceLevel > 1)
 488                    {
 489                        var s = new StringBuilder("retrying locator lookup:\nlookup = ");
 490                        s.Append(_lookup);
 491                        s.Append("\nretry count = ").Append(_pendingRetryCount);
 492                        if (_instanceName.Length > 0)
 493                        {
 494                            s.Append("\ninstance name = ").Append(_instanceName);
 495                        }
 496                        _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 497                    }
 498
 499                    _failureCount = 0;
 500                    ++_generation;
 501                    int generation = _generation;
 502                    foreach (KeyValuePair<LookupPrx, LookupReplyPrx> l in _lookups)
 503                    {
 504                        l.Key.findLocatorAsync(_instanceName, l.Value).ContinueWith(
 505                            t =>
 506                            {
 507                                try
 508                                {
 509                                    t.Wait();
 510                                }
 511                                catch (AggregateException ex)
 512                                {
 513                                    exception(ex.InnerException, generation);
 514                                }
 515                            },
 516                            l.Key.ice_scheduler()); // Send multicast request.
 517                    }
 518                    _timer.schedule(this, _timeout);
 519                    return;
 520                }
 521                catch (Ice.LocalException)
 522                {
 523                }
 524                _pendingRetryCount = 0;
 525            }
 526
 527            Debug.Assert(_pendingRetryCount == 0);
 528            _pending = false;
 529
 530            if (_traceLevel > 0)
 531            {
 532                var s = new StringBuilder("locator lookup timed out:\nlookup = ");
 533                s.Append(_lookup);
 534                if (_instanceName.Length > 0)
 535                {
 536                    s.Append("\ninstance name = ").Append(_instanceName);
 537                }
 538                _lookup.ice_getCommunicator().getLogger().trace("Lookup", s.ToString());
 539            }
 540
 541            if (_pendingRequests.Count > 0)
 542            {
 543                foreach (Request req in _pendingRequests)
 544                {
 545                    req.invoke(_voidLocator);
 546                }
 547                _pendingRequests.Clear();
 548            }
 549            _nextRetry = Ice.Internal.Time.currentMonotonicTimeMillis() + _retryDelay;
 550        }
 551    }
 552
 553    private readonly LookupPrx _lookup;
 554    private readonly Dictionary<LookupPrx, LookupReplyPrx> _lookups = new Dictionary<LookupPrx, LookupReplyPrx>();
 555    private readonly TimeSpan _timeout;
 556    private readonly Ice.Internal.Timer _timer;
 557    private readonly int _traceLevel;
 558    private readonly int _retryCount;
 559    private readonly int _retryDelay;
 560
 561    private string _instanceName;
 562    private bool _warned;
 563    private Ice.LocatorPrx _locator;
 564    private readonly Ice.LocatorPrx _voidLocator;
 565    private readonly Dictionary<string, Ice.LocatorPrx> _locators = new Dictionary<string, Ice.LocatorPrx>();
 566
 567    private bool _pending;
 568    private int _pendingRetryCount;
 569    private int _failureCount;
 570
 571    // Incremented at the start of each lookup round. The findLocatorAsync exception callbacks capture the value current
 572    // when they were sent, so a delayed failure from an earlier round is ignored instead of counting against the
 573    // current round.
 574    private int _generation;
 575    private bool _warnOnce = true;
 576    private readonly List<Request> _pendingRequests = new List<Request>();
 577    private long _nextRetry;
 578    private readonly object _mutex = new();
 579}
 580
 581internal class LookupReplyI : LookupReplyDisp_
 582{
 583    public LookupReplyI(LocatorI locator) => _locator = locator;
 584
 585    public override void
 586    foundLocator(Ice.LocatorPrx locator, Ice.Current current)
 587    {
 588        Ice.ObjectPrx.checkNotNull(locator, current);
 589        _locator.foundLocator(locator);
 590    }
 591
 592    private readonly LocatorI _locator;
 593}
 594
 595internal class PluginI : Ice.Plugin
 596{
 597    public
 598    PluginI(Ice.Communicator communicator) => _communicator = communicator;
 599
 600    public void
 601    initialize()
 602    {
 603        Ice.Properties properties = _communicator.getProperties();
 604
 605        bool ipv4 = properties.getIcePropertyAsInt("Ice.IPv4") > 0;
 606        bool preferIPv6 = properties.getIcePropertyAsInt("Ice.PreferIPv6Address") > 0;
 607        string address = properties.getIceProperty("IceLocatorDiscovery.Address");
 608        if (address.Length == 0)
 609        {
 610            address = ipv4 && !preferIPv6 ? "239.255.0.1" : "ff15::1";
 611        }
 612        int port = properties.getIcePropertyAsInt("IceLocatorDiscovery.Port");
 613        string intf = properties.getIceProperty("IceLocatorDiscovery.Interface");
 614
 615        string lookupEndpoints = properties.getIceProperty("IceLocatorDiscovery.Lookup");
 616        if (lookupEndpoints.Length == 0)
 617        {
 618            int protocol = ipv4 && !preferIPv6 ? Ice.Internal.Network.EnableIPv4 : Ice.Internal.Network.EnableIPv6;
 619            List<string> interfaces = Ice.Internal.Network.getInterfacesForMulticast(intf, protocol);
 620            foreach (string p in interfaces)
 621            {
 622                if (p != interfaces[0])
 623                {
 624                    lookupEndpoints += ":";
 625                }
 626                lookupEndpoints += "udp -h \"" + address + "\" -p " + port + " --interface \"" + p + "\"";
 627            }
 628        }
 629
 630        if (properties.getIceProperty("IceLocatorDiscovery.Reply.Endpoints").Length == 0)
 631        {
 632            properties.setProperty(
 633                "IceLocatorDiscovery.Reply.Endpoints",
 634                "udp -h " + (intf.Length == 0 ? "*" : "\"" + intf + "\""));
 635        }
 636
 637        if (properties.getIceProperty("IceLocatorDiscovery.Locator.Endpoints").Length == 0)
 638        {
 639            properties.setProperty("IceLocatorDiscovery.Locator.AdapterId", Guid.NewGuid().ToString());
 640        }
 641
 642        _replyAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Reply");
 643        _locatorAdapter = _communicator.createObjectAdapter("IceLocatorDiscovery.Locator");
 644
 645        // We don't want those adapters to be registered with the locator so clear their locator.
 646        _replyAdapter.setLocator(null);
 647        _locatorAdapter.setLocator(null);
 648
 649        Ice.ObjectPrx lookupPrx = Ice.ObjectPrxHelper.createProxy(
 650            _communicator,
 651            "IceLocatorDiscovery/Lookup -d:" + lookupEndpoints);
 652
 653        lookupPrx = lookupPrx.ice_router(null);
 654
 655        Ice.LocatorPrx voidLo = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.addWithUUID(new VoidLocatorI()));
 656
 657        string instanceName = properties.getIceProperty("IceLocatorDiscovery.InstanceName");
 658        var id = new Ice.Identity("Locator", instanceName.Length > 0 ? instanceName : Guid.NewGuid().ToString());
 659
 660        _defaultLocator = _communicator.getDefaultLocator();
 661        _locator = new LocatorI(LookupPrxHelper.uncheckedCast(lookupPrx), properties, instanceName, voidLo);
 662        _locatorPrx = Ice.LocatorPrxHelper.uncheckedCast(_locatorAdapter.add(_locator, id));
 663        _communicator.setDefaultLocator(_locatorPrx);
 664
 665        Ice.ObjectPrx lookupReply = _replyAdapter.addWithUUID(new LookupReplyI(_locator)).ice_datagram();
 666        _locator.setLookupReply(LookupReplyPrxHelper.uncheckedCast(lookupReply));
 667
 668        _replyAdapter.activate();
 669        _locatorAdapter.activate();
 670    }
 671
 672    public void
 673    destroy()
 674    {
 675        // Called after initialize() completed successfully.
 676        _replyAdapter?.destroy();
 677        _locatorAdapter?.destroy();
 678        if (_locatorPrx.Equals(_communicator.getDefaultLocator()))
 679        {
 680            // Restore original default locator proxy, if the user didn't change it in the meantime
 681            _communicator.setDefaultLocator(_defaultLocator);
 682        }
 683    }
 684
 685    private readonly Ice.Communicator _communicator;
 686    private Ice.ObjectAdapter _locatorAdapter;
 687    private Ice.ObjectAdapter _replyAdapter;
 688    private LocatorI _locator;
 689    private Ice.LocatorPrx _locatorPrx;
 690    private Ice.LocatorPrx _defaultLocator;
 691}