001/*
002 * (C) Copyright 2017 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 */
017package org.nuxeo.ecm.core.management.standby;
018
019import javax.management.JMException;
020
021import org.nuxeo.ecm.core.api.NuxeoException;
022import org.nuxeo.runtime.api.Framework;
023import org.nuxeo.runtime.management.ServerLocator;
024import org.nuxeo.runtime.metrics.MetricsService;
025import org.nuxeo.runtime.model.ComponentContext;
026import org.nuxeo.runtime.model.DefaultComponent;
027import org.nuxeo.runtime.trackers.concurrent.ThreadEventHandler;
028import org.nuxeo.runtime.trackers.concurrent.ThreadEventListener;
029
030import io.dropwizard.metrics5.Counter;
031import io.dropwizard.metrics5.Meter;
032import io.dropwizard.metrics5.MetricRegistry;
033import io.dropwizard.metrics5.SharedMetricRegistries;
034import io.dropwizard.metrics5.Timer;
035import io.dropwizard.metrics5.Timer.Context;
036
037/**
038 * @since 9.2
039 */
040public class StandbyComponent extends DefaultComponent {
041
042    protected final StandbyCommand command = new StandbyCommand();
043
044    protected MetricRegistry registry = SharedMetricRegistries.getOrCreate(MetricsService.class.getName());
045
046    protected final Counter active = registry.counter(MetricRegistry.name(StandbyComponent.class, "active"));
047
048    protected final Meter meter = registry.meter(MetricRegistry.name(StandbyComponent.class, "meter"));
049
050    protected final Timer timer = registry.timer(MetricRegistry.name(StandbyComponent.class, "timer"));
051
052    protected final ThreadLocal<Context> holder = new ThreadLocal<>();
053
054    protected final ThreadEventListener threadsListener = new ThreadEventListener(new ThreadEventHandler() {
055
056        @Override
057        public void onEnter(boolean isLongRunning) {
058            if (isLongRunning) {
059                return;
060            }
061            holder.set(timer.time());
062            meter.mark();
063            active.inc();
064        }
065
066        @Override
067        public void onLeave() {
068            active.dec();
069            holder.get().close();
070        }
071
072    });
073
074    @Override
075    public void activate(ComponentContext context) {
076        threadsListener.install();
077        try {
078            command.registration.with(Framework.getService(ServerLocator.class).lookupServer()).register();
079        } catch (JMException cause) {
080            throw new NuxeoException("Cannot register standby command", cause);
081        }
082    }
083
084    @Override
085    public void deactivate(ComponentContext context) {
086        threadsListener.uninstall();
087        try {
088            command.registration.unregister();
089        } catch (JMException cause) {
090            throw new NuxeoException("Cannot unregister standby command", cause);
091        }
092    }
093
094}