package io.muoncore.transport;
import io.muoncore.InstanceDescriptor;
import io.muoncore.ServiceDescriptor;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class ServiceCache {
static final int EXPIRY = 5000;
private Map<String, Entry> serviceCache = Collections.synchronizedMap(new HashMap<>());
private boolean expiring = true;
public ServiceCache() {
this.expiring = true;
}
public ServiceCache(boolean expiring) {
this.expiring = expiring;
}
public void addService(InstanceDescriptor service) {
service.validate();
Entry entry = serviceCache.get(service.getIdentifier());
if (entry == null) {
entry = new Entry(service);
} else {
entry.touch(service);
}
serviceCache.put(
service.getIdentifier(), entry);
}
private synchronized void expire() {
Map<String, Entry> newCache = new HashMap<>(serviceCache);
Map<String, Entry> entries = new HashMap<>();
for (Map.Entry<String, Entry> entry : newCache.entrySet()) {
long val = entry.getValue().createdAt + EXPIRY - System.currentTimeMillis();
if (val > 0) {
entries.put(entry.getKey(), entry.getValue());
}
}
serviceCache = Collections.synchronizedMap(entries);
}
public List<ServiceDescriptor> getServices() {
if (expiring) {
expire();
}
return this.serviceCache.values().stream().map(val -> val.data).collect(Collectors.toList());
}
static class Entry {
ServiceDescriptor data;
long createdAt;
Entry(InstanceDescriptor descriptor) {
createdAt = System.currentTimeMillis();
List<InstanceDescriptor> instances = new ArrayList<>();
instances.add(descriptor);
this.data = new ServiceDescriptor(descriptor.getIdentifier(),
descriptor.getTags(), descriptor.getCodecs(),
descriptor.getCapabilities(),
instances);
}
void touch(InstanceDescriptor descriptor) {
createdAt = System.currentTimeMillis();
if (descriptor == null) {
log.error("Got a null descriptor!");
}
data.getInstanceDescriptors().removeIf(integer -> integer.getInstanceId().equals(descriptor.getInstanceId()));
data.getInstanceDescriptors().add(descriptor);
}
}
}