diff options
author | Håkon Hallingstad <hakon@oath.com> | 2017-09-29 08:57:20 +0200 |
---|---|---|
committer | Håkon Hallingstad <hakon@oath.com> | 2017-09-29 12:38:31 +0200 |
commit | 4d29c806e4d3a85a0c91aea0862b1fd2f4b86eef (patch) | |
tree | 8122ca15f6b8e7dc7731fc1f8f17c7abdb4f8fb4 /service-monitor/src/main | |
parent | ea33246cad6196a6b43266099df509993e83ae85 (diff) |
Adds listener for SuperModel changes
Diffstat (limited to 'service-monitor/src/main')
-rw-r--r-- | service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java | 44 | ||||
-rw-r--r-- | service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java | 67 |
2 files changed, 111 insertions, 0 deletions
diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java new file mode 100644 index 00000000000..3468644169d --- /dev/null +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/ServiceMonitorImpl.java @@ -0,0 +1,44 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.service.monitor; + +import com.google.inject.Inject; +import com.yahoo.cloud.config.ConfigserverConfig; +import com.yahoo.config.model.api.SuperModelProvider; +import com.yahoo.config.provision.Zone; +import com.yahoo.vespa.applicationmodel.ApplicationInstance; +import com.yahoo.vespa.applicationmodel.ApplicationInstanceReference; + +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public class ServiceMonitorImpl implements ServiceMonitor { + private static final Logger logger = Logger.getLogger(ServiceMonitorImpl.class.getName()); + + private final Zone zone; + private final List<String> configServerHostnames; + private final SlobrokMonitor2 slobrokMonitor = new SlobrokMonitor2(); + private final SuperModelListenerImpl superModelListener = + new SuperModelListenerImpl(slobrokMonitor); + + @Inject + public ServiceMonitorImpl(SuperModelProvider superModelProvider, + ConfigserverConfig configserverConfig) { + this.zone = superModelProvider.getZone(); + this.configServerHostnames = configserverConfig.zookeeperserver().stream() + .map(server -> server.hostname()) + .collect(Collectors.toList()); + superModelListener.start(superModelProvider); + } + + @Override + public Map<ApplicationInstanceReference, + ApplicationInstance<ServiceMonitorStatus>> queryStatusOfAllApplicationInstances() { + // If we ever need to optimize this method, then consider reusing ServiceModel snapshots + // for up to X ms. + ServiceModel serviceModel = + superModelListener.createServiceModelSnapshot(zone, configServerHostnames); + return serviceModel.getAllApplicationInstances(); + } +} diff --git a/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java new file mode 100644 index 00000000000..8beb90c382a --- /dev/null +++ b/service-monitor/src/main/java/com/yahoo/vespa/service/monitor/SuperModelListenerImpl.java @@ -0,0 +1,67 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.service.monitor; + +import com.yahoo.config.model.api.SuperModel; +import com.yahoo.config.model.api.SuperModelListener; +import com.yahoo.config.model.api.SuperModelProvider; +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.Zone; + +import java.util.List; +import java.util.logging.Logger; + +public class SuperModelListenerImpl implements SuperModelListener { + private static final Logger logger = Logger.getLogger(SuperModelListenerImpl.class.getName()); + + // Guard for updating superModel and slobrokMonitor exclusively and atomically: + // - superModel and slobrokMonitor must be updated in combination (exclusively and atomically) + // - Anyone may take a snapshot of superModel for reading purposes, hence volatile. + private final Object monitor = new Object(); + private final SlobrokMonitor2 slobrokMonitor; + private volatile SuperModel superModel; + + SuperModelListenerImpl(SlobrokMonitor2 slobrokMonitor) { + this.slobrokMonitor = slobrokMonitor; + } + + void start(SuperModelProvider superModelProvider) { + synchronized (monitor) { + // This snapshot() call needs to be within the synchronized block, + // since applicationActivated()/applicationRemoved() may be called + // asynchronously even before snapshot() returns. + SuperModel snapshot = superModelProvider.snapshot(this); + exclusiveUpdate(snapshot); + } + } + + @Override + public void applicationActivated(SuperModel superModel, ApplicationId applicationId) { + synchronized (monitor) { + exclusiveUpdate(superModel); + } + } + + @Override + public void applicationRemoved(SuperModel superModel, ApplicationId id) { + synchronized (monitor) { + exclusiveUpdate(superModel); + } + } + + ServiceModel createServiceModelSnapshot(Zone zone, List<String> configServerHostnames) { + // Save a snapshot of volatile this.superModel outside of synchronized block. + SuperModel superModelSnapshot = this.superModel; + + ModelGenerator modelGenerator = new ModelGenerator(); + return modelGenerator.toServiceModel( + superModelSnapshot, + zone, + configServerHostnames, + slobrokMonitor); + } + + private void exclusiveUpdate(SuperModel superModel) { + this.superModel = superModel; + slobrokMonitor.updateSlobrokList(superModel); + } +}
\ No newline at end of file |