Merge "De-duplicate questions with multiple listeners" into main
This commit is contained in:
commit
d4b802064b
2 changed files with 43 additions and 6 deletions
|
|
@ -140,8 +140,7 @@ public class MdnsServiceTypeClient {
|
|||
// before sending the query, it needs to be called just before sending it.
|
||||
final List<MdnsResponse> servicesToResolve = makeResponsesForResolve(socketKey);
|
||||
final QueryTask queryTask = new QueryTask(taskArgs, servicesToResolve,
|
||||
getAllDiscoverySubtypes(),
|
||||
servicesToResolve.size() < listeners.size() /* sendDiscoveryQueries */);
|
||||
getAllDiscoverySubtypes(), needSendDiscoveryQueries(listeners));
|
||||
executor.submit(queryTask);
|
||||
break;
|
||||
}
|
||||
|
|
@ -388,8 +387,7 @@ public class MdnsServiceTypeClient {
|
|||
final QueryTask queryTask = new QueryTask(
|
||||
mdnsQueryScheduler.scheduleFirstRun(taskConfig, now,
|
||||
minRemainingTtl, currentSessionId), servicesToResolve,
|
||||
getAllDiscoverySubtypes(),
|
||||
servicesToResolve.size() < listeners.size() /* sendDiscoveryQueries */);
|
||||
getAllDiscoverySubtypes(), needSendDiscoveryQueries(listeners));
|
||||
executor.submit(queryTask);
|
||||
}
|
||||
|
||||
|
|
@ -627,6 +625,10 @@ public class MdnsServiceTypeClient {
|
|||
if (resolveName == null) {
|
||||
continue;
|
||||
}
|
||||
if (CollectionUtils.any(resolveResponses,
|
||||
r -> MdnsUtils.equalsIgnoreDnsCase(resolveName, r.getServiceInstanceName()))) {
|
||||
continue;
|
||||
}
|
||||
MdnsResponse knownResponse =
|
||||
serviceCache.getCachedService(resolveName, cacheKey);
|
||||
if (knownResponse == null) {
|
||||
|
|
@ -643,6 +645,17 @@ public class MdnsServiceTypeClient {
|
|||
return resolveResponses;
|
||||
}
|
||||
|
||||
private static boolean needSendDiscoveryQueries(
|
||||
@NonNull ArrayMap<MdnsServiceBrowserListener, ListenerInfo> listeners) {
|
||||
// Note iterators are discouraged on ArrayMap as per its documentation
|
||||
for (int i = 0; i < listeners.size(); i++) {
|
||||
if (listeners.valueAt(i).searchOptions.getResolveInstanceName() == null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void tryRemoveServiceAfterTtlExpires() {
|
||||
if (!shouldRemoveServiceAfterTtlExpires()) return;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ import static org.mockito.Mockito.inOrder;
|
|||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
|
@ -1207,10 +1208,14 @@ public class MdnsServiceTypeClientTests {
|
|||
final String ipV4Address = "192.0.2.0";
|
||||
final String ipV6Address = "2001:db8::";
|
||||
|
||||
final MdnsSearchOptions resolveOptions = MdnsSearchOptions.newBuilder()
|
||||
final MdnsSearchOptions resolveOptions1 = MdnsSearchOptions.newBuilder()
|
||||
.setResolveInstanceName(instanceName).build();
|
||||
final MdnsSearchOptions resolveOptions2 = MdnsSearchOptions.newBuilder()
|
||||
.setResolveInstanceName(instanceName).build();
|
||||
|
||||
startSendAndReceive(mockListenerOne, resolveOptions);
|
||||
startSendAndReceive(mockListenerOne, resolveOptions1);
|
||||
startSendAndReceive(mockListenerTwo, resolveOptions2);
|
||||
// No need to verify order for both listeners; and order is not guaranteed between them
|
||||
InOrder inOrder = inOrder(mockListenerOne, mockSocketClient);
|
||||
|
||||
// Verify a query for SRV/TXT was sent, but no PTR query
|
||||
|
|
@ -1223,13 +1228,19 @@ public class MdnsServiceTypeClientTests {
|
|||
eq(socketKey), eq(false));
|
||||
verify(mockDeps, times(1)).sendMessage(any(), any(Message.class));
|
||||
assertNotNull(delayMessage);
|
||||
inOrder.verify(mockListenerOne).onDiscoveryQuerySent(any(), anyInt());
|
||||
verify(mockListenerTwo).onDiscoveryQuerySent(any(), anyInt());
|
||||
|
||||
final MdnsPacket srvTxtQueryPacket = MdnsPacket.parse(
|
||||
new MdnsPacketReader(srvTxtQueryCaptor.getValue()));
|
||||
|
||||
final String[] serviceName = getTestServiceName(instanceName);
|
||||
assertEquals(1, srvTxtQueryPacket.questions.size());
|
||||
assertFalse(hasQuestion(srvTxtQueryPacket, MdnsRecord.TYPE_PTR));
|
||||
assertTrue(hasQuestion(srvTxtQueryPacket, MdnsRecord.TYPE_ANY, serviceName));
|
||||
assertEquals(0, srvTxtQueryPacket.answers.size());
|
||||
assertEquals(0, srvTxtQueryPacket.authorityRecords.size());
|
||||
assertEquals(0, srvTxtQueryPacket.additionalRecords.size());
|
||||
|
||||
// Process a response with SRV+TXT
|
||||
final MdnsPacket srvTxtResponse = new MdnsPacket(
|
||||
|
|
@ -1246,6 +1257,10 @@ public class MdnsServiceTypeClientTests {
|
|||
Collections.emptyList() /* additionalRecords */);
|
||||
|
||||
processResponse(srvTxtResponse, socketKey);
|
||||
inOrder.verify(mockListenerOne).onServiceNameDiscovered(
|
||||
matchServiceName(instanceName), eq(false) /* isServiceFromCache */);
|
||||
verify(mockListenerTwo).onServiceNameDiscovered(
|
||||
matchServiceName(instanceName), eq(false) /* isServiceFromCache */);
|
||||
|
||||
// Expect a query for A/AAAA
|
||||
dispatchMessage();
|
||||
|
|
@ -1255,11 +1270,18 @@ public class MdnsServiceTypeClientTests {
|
|||
inOrder.verify(mockSocketClient, times(2)).sendPacketRequestingMulticastResponse(
|
||||
addressQueryCaptor.capture(),
|
||||
eq(socketKey), eq(false));
|
||||
inOrder.verify(mockListenerOne).onDiscoveryQuerySent(any(), anyInt());
|
||||
// onDiscoveryQuerySent was called 2 times in total
|
||||
verify(mockListenerTwo, times(2)).onDiscoveryQuerySent(any(), anyInt());
|
||||
|
||||
final MdnsPacket addressQueryPacket = MdnsPacket.parse(
|
||||
new MdnsPacketReader(addressQueryCaptor.getValue()));
|
||||
assertEquals(2, addressQueryPacket.questions.size());
|
||||
assertTrue(hasQuestion(addressQueryPacket, MdnsRecord.TYPE_A, hostname));
|
||||
assertTrue(hasQuestion(addressQueryPacket, MdnsRecord.TYPE_AAAA, hostname));
|
||||
assertEquals(0, addressQueryPacket.answers.size());
|
||||
assertEquals(0, addressQueryPacket.authorityRecords.size());
|
||||
assertEquals(0, addressQueryPacket.additionalRecords.size());
|
||||
|
||||
// Process a response with address records
|
||||
final MdnsPacket addressResponse = new MdnsPacket(
|
||||
|
|
@ -1276,10 +1298,12 @@ public class MdnsServiceTypeClientTests {
|
|||
Collections.emptyList() /* additionalRecords */);
|
||||
|
||||
inOrder.verify(mockListenerOne, never()).onServiceNameDiscovered(any(), anyBoolean());
|
||||
verifyNoMoreInteractions(mockListenerTwo);
|
||||
processResponse(addressResponse, socketKey);
|
||||
|
||||
inOrder.verify(mockListenerOne).onServiceFound(
|
||||
serviceInfoCaptor.capture(), eq(false) /* isServiceFromCache */);
|
||||
verify(mockListenerTwo).onServiceFound(any(), anyBoolean());
|
||||
verifyServiceInfo(serviceInfoCaptor.getValue(),
|
||||
instanceName,
|
||||
SERVICE_TYPE_LABELS,
|
||||
|
|
|
|||
Loading…
Reference in a new issue