@Override
    public void subscribeServiceInstance(String serviceName, XdsServiceDiscoveryListener listener) {
        // cache listener
        XdsDataCache.addServiceDiscoveryListener(serviceName, listener);

        // first check the cache and return if service instance exists
        if (XdsDataCache.isContainsRequestObserver(serviceName)) {
            listener.process(XdsDataCache.getServiceInstance(serviceName));
            return;
        }

        // locking ensures that a service only creates one stream
        LOCK.lock();
        try {
            // check the cache again after locking and notify listener if service instance exists
            if (XdsDataCache.isContainsRequestObserver(serviceName)) {
                listener.process(XdsDataCache.getServiceInstance(serviceName));
                return;
            }

            // subscribe service instance
            edsHandler.subscribe(serviceName, null);
        } finally {
            LOCK.unlock();
        }
    }
@Test
    public void subscribeServiceInstance() {
        // clear data
        XdsDataCache.removeServiceInstance(serviceName);
        XdsDataCache.removeServiceDiscoveryListeners(serviceName);
        XdsDataCache.removeRequestObserver(serviceName);

        // no service instance in cache
        XdsServiceDiscoveryListenerImpl xdsServiceDiscoveryListener = new XdsServiceDiscoveryListenerImpl();
        xdsServiceDiscovery.subscribeServiceInstance(serviceName, xdsServiceDiscoveryListener);
        Assert.assertEquals(1, XdsDataCache.getServiceDiscoveryListeners(serviceName).size());
        Assert.assertEquals(0, xdsServiceDiscoveryListener.getCount());

        // service instance in cache
        Set<ServiceInstance> instances = new HashSet<>();
        instances.add(new XdsServiceInstance());
        XdsDataCache.updateServiceInstance(serviceName, instances);
        xdsServiceDiscovery.subscribeServiceInstance(serviceName, xdsServiceDiscoveryListener);
        Assert.assertEquals(1, xdsServiceDiscoveryListener.getCount());
    }