Skip to content

Commit

Permalink
Merge pull request #283 from JeffersonLab/nbrei_service_component
Browse files Browse the repository at this point in the history
JService is now a JComponent
  • Loading branch information
nathanwbrei authored Apr 15, 2024
2 parents c91175c + e2b2982 commit 0d7fb91
Show file tree
Hide file tree
Showing 19 changed files with 576 additions and 452 deletions.
2 changes: 1 addition & 1 deletion src/libraries/JANA/CLI/JBenchmarker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#include "JBenchmarker.h"

#include <JANA/Utils/JCpuInfo.h>
#include <JANA/JLogger.h>
#include <JANA/Services/JLoggingService.h>

#include <fstream>
#include <cmath>
Expand Down
1 change: 1 addition & 0 deletions src/libraries/JANA/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(JANA2_SOURCES
JLogger.h
JMultifactory.cc
JMultifactory.h
JService.cc

Engine/JArrow.h
Engine/JArrowMetrics.h
Expand Down
66 changes: 34 additions & 32 deletions src/libraries/JANA/JApplication.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,33 @@

#include <JANA/JApplication.h>

#include <JANA/JEventProcessor.h>
#include <JANA/JEventSource.h>
#include <JANA/JEventSourceGenerator.h>
#include <JANA/JFactoryGenerator.h>

#include <JANA/Services/JParameterManager.h>
#include <JANA/Services/JPluginLoader.h>
#include <JANA/Services/JComponentManager.h>
#include <JANA/Services/JGlobalRootLock.h>
#include <JANA/Engine/JArrowProcessingController.h>
#include <JANA/Utils/JCpuInfo.h>
#include <JANA/Utils/JAutoActivator.h>
#include <JANA/Engine/JTopologyBuilder.h>

JApplication *japp = nullptr;

JApplication::JApplication(JLogger::Level verbosity) {
m_service_locator = new JServiceLocator;
m_params = std::make_shared<JParameterManager>();
m_params->SetParameter("log:global", verbosity);
m_service_locator.provide(m_params);
m_service_locator.provide(std::make_shared<JLoggingService>());
m_service_locator.provide(std::make_shared<JPluginLoader>(this));
m_service_locator.provide(std::make_shared<JComponentManager>(this));
m_service_locator.provide(std::make_shared<JGlobalRootLock>());
m_service_locator.provide(std::make_shared<JTopologyBuilder>());

m_plugin_loader = m_service_locator.get<JPluginLoader>();
m_component_manager = m_service_locator.get<JComponentManager>();
m_logger = m_service_locator.get<JLoggingService>()->get_logger("JApplication");
m_service_locator->provide(m_params);
ProvideService(m_params);
ProvideService(std::make_shared<JLoggingService>());
ProvideService(std::make_shared<JPluginLoader>());
ProvideService(std::make_shared<JComponentManager>());
ProvideService(std::make_shared<JGlobalRootLock>());
ProvideService(std::make_shared<JTopologyBuilder>());

m_plugin_loader = m_service_locator->get<JPluginLoader>();
m_component_manager = m_service_locator->get<JComponentManager>();
m_logger = m_service_locator->get<JLoggingService>()->get_logger("JApplication");
m_logger.show_classname = false;
}

Expand All @@ -45,17 +43,18 @@ JApplication::JApplication(JParameterManager* params) {
m_params = std::shared_ptr<JParameterManager>(params);
}

m_service_locator.provide(m_params);
m_service_locator.provide(std::make_shared<JLoggingService>());
m_service_locator.provide(std::make_shared<JPluginLoader>(this));
m_service_locator.provide(std::make_shared<JComponentManager>(this));
m_service_locator.provide(std::make_shared<JGlobalRootLock>());
m_service_locator.provide(std::make_shared<JTopologyBuilder>());
m_service_locator = new JServiceLocator;
ProvideService(m_params);
ProvideService(std::make_shared<JLoggingService>());
ProvideService(std::make_shared<JPluginLoader>());
ProvideService(std::make_shared<JComponentManager>());
ProvideService(std::make_shared<JGlobalRootLock>());
ProvideService(std::make_shared<JTopologyBuilder>());

m_plugin_loader = m_service_locator.get<JPluginLoader>();
m_component_manager = m_service_locator.get<JComponentManager>();
m_plugin_loader = m_service_locator->get<JPluginLoader>();
m_component_manager = m_service_locator->get<JComponentManager>();

m_logger = m_service_locator.get<JLoggingService>()->get_logger("JApplication");
m_logger = m_service_locator->get<JLoggingService>()->get_logger("JApplication");
m_logger.show_classname = false;
}

Expand Down Expand Up @@ -119,13 +118,17 @@ void JApplication::Initialize() {
// Only run this once
if (m_initialized) return;

// Obtain final values of parameters and loggers
m_plugin_loader->InitPhase2();
m_component_manager->InitPhase2();
m_logger = m_service_locator->get<JLoggingService>()->get_logger("JApplication");
m_logger.show_classname = false;

// Attach all plugins
m_plugin_loader->attach_plugins(m_component_manager.get());

// Look for factories to auto-activate
if (JAutoActivator::IsRequested(m_params)) {
m_component_manager->add(new JAutoActivator);
}
// Resolve all event sources now that all plugins have been loaded
m_component_manager->resolve_event_sources();

// Set desired nthreads. We parse the 'nthreads' parameter two different ways for backwards compatibility.
m_desired_nthreads = 1;
Expand All @@ -137,7 +140,6 @@ void JApplication::Initialize() {
m_params->SetDefaultParameter("jana:ticker_interval", m_ticker_interval_ms, "Controls the ticker interval (in ms)");
m_params->SetDefaultParameter("jana:extended_report", m_extended_report, "Controls whether the ticker shows simple vs detailed performance metrics");

m_component_manager->initialize();

/*
int engine_choice = 0;
Expand All @@ -148,13 +150,13 @@ void JApplication::Initialize() {
LOG_WARN(m_logger) << "Unrecognized engine choice! Falling back to jana:engine=0" << LOG_END;
}
*/
std::shared_ptr<JTopologyBuilder> topology_builder = m_service_locator.get<JTopologyBuilder>();
std::shared_ptr<JTopologyBuilder> topology_builder = m_service_locator->get<JTopologyBuilder>();
auto topology = topology_builder->get_or_create();

auto japc = std::make_shared<JArrowProcessingController>(topology);
m_service_locator.provide(japc); // Make concrete class available via SL
m_processing_controller = m_service_locator.get<JArrowProcessingController>(); // Get deps from SL
m_service_locator.provide(m_processing_controller); // Make abstract class available via SL
m_service_locator->provide(japc); // Make concrete class available via SL
m_processing_controller = m_service_locator->get<JArrowProcessingController>(); // Get deps from SL
m_service_locator->provide(m_processing_controller); // Make abstract class available via SL
m_processing_controller->initialize();

m_initialized = true;
Expand Down
173 changes: 5 additions & 168 deletions src/libraries/JANA/JApplication.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,164 +2,11 @@
// Copyright 2020, Jefferson Science Associates, LLC.
// Subject to the terms in the LICENSE file found in the top-level directory.

#ifndef _JApplication_h_
#define _JApplication_h_

#include <vector>
#include <string>
#include <iostream>
#include <atomic>

class JApplication;
class JEventProcessor;
class JEventSource;
class JEventSourceGenerator;
class JFactoryGenerator;
class JFactorySet;
class JComponentManager;
class JPluginLoader;
class JProcessingController;
class JEventUnfolder;

extern JApplication* japp;
#pragma once
#include <JANA/JApplicationFwd.h>

#include <JANA/Services/JServiceLocator.h>
#include <JANA/Services/JParameterManager.h>
#include <JANA/Services/JLoggingService.h>
#include <JANA/Status/JComponentSummary.h>
#include <JANA/Status/JPerfSummary.h>


//////////////////////////////////////////////////////////////////////////////////////////////////
/// JANA application class
///
/// The JApplication class serves as a central access point for getting to most things
/// in the JANA application. It owns the JThreadManager, JParameterManager, etc.
/// It is also responsible for making sure all of the plugins are attached and other
/// user specified configurations for the run are implemented before starting the processing
/// of the data. User code (e.g. plugins) will generally register things like event sources
/// and processors with the JApplication so they can be called up later at the appropriate time.
//////////////////////////////////////////////////////////////////////////////////////////////////
class JApplication {

public:

/// These exit codes are what JANA uses internally. However they are fundamentally a suggestion --
/// the user code is likely to use arbitrary exit codes.
enum class ExitCode {Success=0, UnhandledException, Timeout, Segfault=139};

explicit JApplication(JParameterManager* params = nullptr);
explicit JApplication(JLogger::Level verbosity);
~JApplication();


// Loading plugins

void AddPlugin(std::string plugin_name);
void AddPluginPath(std::string path);


// Building a JProcessingTopology

void Add(std::string event_source_name);
void Add(JEventSourceGenerator* source_generator);
void Add(JFactoryGenerator* factory_generator);
void Add(JEventSource* event_source);
void Add(JEventProcessor* processor);
void Add(JEventUnfolder* unfolder);


// Controlling processing

void Initialize(void);
void Run(bool wait_until_finished = true);
void Scale(int nthreads);
void Stop(bool wait_until_idle = false);
void Resume() {}; // TODO: Do we need this?
void Quit(bool skip_join = false);
void SetExitCode(int exitCode);
int GetExitCode();


// Performance/status monitoring

bool IsInitialized(void){return m_initialized;}
bool IsQuitting(void) { return m_quitting; }
bool IsDrainingQueues(void) { return m_draining_queues; }

void SetTicker(bool ticker_on = true);
bool IsTickerEnabled();
void SetTimeoutEnabled(bool enabled = true);
bool IsTimeoutEnabled();
void PrintStatus();
void PrintFinalReport();
uint64_t GetNThreads();
uint64_t GetNEventsProcessed();
float GetIntegratedRate();
float GetInstantaneousRate();

JComponentSummary GetComponentSummary();

// Parameter config

JParameterManager* GetJParameterManager() { return m_params.get(); }

template<typename T>
T GetParameterValue(std::string name);

template <typename T>
JParameter* GetParameter(std::string name, T& val);

template<typename T>
JParameter* SetParameterValue(std::string name, T val);

template <typename T>
JParameter* SetDefaultParameter(std::string name, T& val, std::string description="");

template <typename T>
T RegisterParameter(std::string name, const T default_val, std::string description="");

// Locating services

/// Use this in EventSources, Factories, or EventProcessors. Do not call this
/// from InitPlugin(), as not all JServices may have been loaded yet.
/// When initializing a Service, use acquire_services() instead.
template <typename T>
std::shared_ptr<T> GetService();

/// Call this from InitPlugin.
template <typename T>
void ProvideService(std::shared_ptr<T> service);


private:

JLogger m_logger;
JServiceLocator m_service_locator;

std::shared_ptr<JParameterManager> m_params;
std::shared_ptr<JPluginLoader> m_plugin_loader;
std::shared_ptr<JComponentManager> m_component_manager;
std::shared_ptr<JProcessingController> m_processing_controller;

bool m_quitting = false;
bool m_draining_queues = false;
bool m_skip_join = false;
std::atomic_bool m_initialized {false};
bool m_ticker_on = true;
bool m_timeout_on = true;
bool m_extended_report = false;
int m_exit_code = (int) ExitCode::Success;
int m_desired_nthreads;

std::mutex m_status_mutex;
int m_ticker_interval_ms = 1000;
std::chrono::time_point<std::chrono::high_resolution_clock> m_last_measurement;
std::unique_ptr<const JPerfSummary> m_perf_summary;

void update_status();
};



/// A convenience method which delegates to JParameterManager
Expand Down Expand Up @@ -192,25 +39,15 @@ JParameter* JApplication::GetParameter(std::string name, T& result) {
/// A convenience method which delegates to JServiceLocator
template <typename T>
std::shared_ptr<T> JApplication::GetService() {
return m_service_locator.get<T>();
return m_service_locator->get<T>();
}

/// A convenience method which delegates to JServiceLocator
template <typename T>
void JApplication::ProvideService(std::shared_ptr<T> service) {
m_service_locator.provide(service);
service->SetApplication(this);
m_service_locator->provide(service);
}



// This routine is used to bootstrap plugins. It is done outside
// of the JApplication class to ensure it sees the global variables
// that the rest of the plugin's InitPlugin routine sees.
inline void InitJANAPlugin(JApplication* app) {
// Make sure global pointers are pointing to the
// same ones being used by executable
japp = app;
}

#endif // _JApplication_h_

Loading

0 comments on commit 0d7fb91

Please sign in to comment.