All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.co.real_logic.artio.GatewayProcess Maven / Gradle / Ivy

/*
 * Copyright 2015-2024 Real Logic Limited, Adaptive Financial Consulting Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package uk.co.real_logic.artio;

import io.aeron.Aeron;
import io.aeron.archive.client.AeronArchive;
import org.agrona.ErrorHandler;
import org.agrona.LangUtil;
import org.agrona.concurrent.Agent;
import org.agrona.concurrent.AgentInvoker;
import org.agrona.concurrent.CompositeAgent;
import org.agrona.concurrent.SystemEpochClock;
import uk.co.real_logic.artio.engine.FixEngine;
import uk.co.real_logic.artio.timing.HistogramLogAgent;
import uk.co.real_logic.artio.timing.Timer;

import java.nio.channels.ClosedByInterruptException;
import java.util.ArrayList;
import java.util.List;

import static uk.co.real_logic.artio.CommonConfiguration.TIME_MESSAGES;
import static uk.co.real_logic.artio.dictionary.generation.Exceptions.closeAll;

public abstract class GatewayProcess implements AutoCloseable
{
    /** Common id used by messages in both engine and library */
    public static final long NO_CORRELATION_ID = 0;

    public static final long NO_CONNECTION_ID = -1;

    protected CommonConfiguration configuration;
    protected MonitoringFile monitoringFile;
    protected FixCounters fixCounters;
    protected ErrorHandler errorHandler;
    protected Aeron aeron;
    protected MonitoringAgent monitoringAgent;
    protected Agent monitoringCompositeAgent;

    protected void init(final CommonConfiguration configuration, final int libraryId)
    {
        this.configuration = configuration;
        initMonitoring(configuration);
        initAeron(configuration, libraryId);
    }

    protected abstract boolean shouldRethrowExceptionInErrorHandler();

    protected void initMonitoring(final CommonConfiguration configuration)
    {
        monitoringFile = new MonitoringFile(true, configuration);
        errorHandler = configuration.errorHandlerFactory().make(monitoringFile.errorBuffer());
    }

    public Agent conductorAgent()
    {
        final AgentInvoker invoker = aeron.conductorAgentInvoker();
        if (invoker == null)
        {
            return null;
        }

        return invoker.agent();
    }

    protected void initAeron(final CommonConfiguration configuration, final int libraryId)
    {
        final Aeron.Context context = configureAeronContext(configuration);
        aeron = Aeron.connect(context);
        CloseChecker.onOpen(context.aeronDirectoryName(), aeron);
        fixCounters = new FixCounters(aeron, this instanceof FixEngine, libraryId);
    }

    protected Aeron.Context configureAeronContext(final CommonConfiguration configuration)
    {
        final Aeron.Context ctx = configuration.aeronContext();
        ctx.errorHandler(
            (throwable) ->
            {
                if (shouldRethrowExceptionInErrorHandler())
                {
                    LangUtil.rethrowUnchecked(throwable);
                }

                if (!(throwable instanceof ClosedByInterruptException))
                {
                    errorHandler.onError(throwable);
                }
            });

        return ctx;
    }

    protected void initMonitoringAgent(
        final List timers,
        final CommonConfiguration configuration,
        final AeronArchive aeronArchive,
        final Agent agent)
    {
        final List agents = new ArrayList<>();
        if (TIME_MESSAGES)
        {
            agents.add(new HistogramLogAgent(
                timers,
                configuration.histogramLoggingFile(),
                configuration.histogramPollPeriodInMs(),
                errorHandler,
                new SystemEpochClock(),
                configuration.histogramHandler(),
                configuration.agentNamePrefix()));
        }

        final MonitoringAgentFactory monitoringAgentFactory = configuration.monitoringAgentFactory();
        if (monitoringAgentFactory != null)
        {
            monitoringAgent = monitoringAgentFactory.make(
                monitoringFile.errorBuffer(),
                configuration.agentNamePrefix(),
                aeronArchive);
            agents.add(monitoringAgent);
        }

        if (agent != null)
        {
            agents.add(agent);
        }

        if (!agents.isEmpty())
        {
            this.monitoringCompositeAgent = new CompositeAgent(agents);
        }
    }

    public void close()
    {
        closeAll(
            fixCounters,
            () ->
            {
                aeron.close();
                // Only record this as closed if the aeron.close() succeeded.
                CloseChecker.onClose(configuration.aeronContext().aeronDirectoryName(), aeron);
            },
            monitoringFile);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy