diff --git a/applications/graph-store-catalog/build.gradle b/applications/graph-store-catalog/build.gradle index 0858912847..dec5d0d50c 100644 --- a/applications/graph-store-catalog/build.gradle +++ b/applications/graph-store-catalog/build.gradle @@ -38,6 +38,7 @@ dependencies { implementation project(':graph-schema-api') implementation project(':logging') implementation project(':memory-usage') + implementation project(':metrics-api') implementation project(':native-projection') implementation project(':neo4j-api') implementation project(':progress-tracking') diff --git a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java index baf0ff0183..0829b9615c 100644 --- a/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java +++ b/applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacade.java @@ -43,6 +43,7 @@ import org.neo4j.gds.graphsampling.RandomWalkBasedNodesSampler; import org.neo4j.gds.graphsampling.config.RandomWalkWithRestartsConfig; import org.neo4j.gds.logging.Log; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.projection.GraphProjectNativeResult; import org.neo4j.gds.results.MemoryEstimateResult; import org.neo4j.gds.transaction.TransactionContext; @@ -107,6 +108,7 @@ public class DefaultCatalogBusinessFacade implements CatalogBusinessFacade { private final GraphSamplingApplication graphSamplingApplication; private final EstimateCommonNeighbourAwareRandomWalkApplication estimateCommonNeighbourAwareRandomWalkApplication; private final GenerateGraphApplication generateGraphApplication; + private final ProjectionMetricsService projectionMetricsService; public DefaultCatalogBusinessFacade( Log log, @@ -132,7 +134,8 @@ public DefaultCatalogBusinessFacade( WriteNodePropertiesApplication writeNodePropertiesApplication, WriteRelationshipPropertiesApplication writeRelationshipPropertiesApplication, WriteNodeLabelApplication writeNodeLabelApplication, - WriteRelationshipsApplication writeRelationshipsApplication + WriteRelationshipsApplication writeRelationshipsApplication, + ProjectionMetricsService projectionMetricsService ) { this.log = log; @@ -160,6 +163,7 @@ public DefaultCatalogBusinessFacade( this.graphSamplingApplication = graphSamplingApplication; this.estimateCommonNeighbourAwareRandomWalkApplication = estimateCommonNeighbourAwareRandomWalkApplication; this.generateGraphApplication = generateGraphApplication; + this.projectionMetricsService = projectionMetricsService; } @Override @@ -230,16 +234,23 @@ public GraphProjectNativeResult nativeProject( rawConfiguration ); - return nativeProjectApplication.project( - databaseId, - graphDatabaseService, - graphProjectMemoryUsageService, - taskRegistryFactory, - terminationFlag, - transactionContext, - userLogRegistryFactory, - configuration - ); + var projectMetric = projectionMetricsService.createNative(); + try(projectMetric) { + projectMetric.start(); + return nativeProjectApplication.project( + databaseId, + graphDatabaseService, + graphProjectMemoryUsageService, + taskRegistryFactory, + terminationFlag, + transactionContext, + userLogRegistryFactory, + configuration + ); + } catch (Exception e) { + projectMetric.failed(); + throw e; + } } @Override @@ -296,16 +307,23 @@ public GraphProjectCypherResult cypherProject( rawConfiguration ); - return cypherProjectApplication.project( - databaseId, - graphDatabaseService, - graphProjectMemoryUsageService, - taskRegistryFactory, - terminationFlag, - transactionContext, - userLogRegistryFactory, - configuration - ); + var projectMetric = projectionMetricsService.createCypher(); + try(projectMetric) { + projectMetric.start(); + return cypherProjectApplication.project( + databaseId, + graphDatabaseService, + graphProjectMemoryUsageService, + taskRegistryFactory, + terminationFlag, + transactionContext, + userLogRegistryFactory, + configuration + ); + } catch (Exception e) { + projectMetric.failed(); + throw e; + } } @Override diff --git a/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java b/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java index ff975f4fe4..143a43edd0 100644 --- a/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java +++ b/applications/graph-store-catalog/src/test/java/org/neo4j/gds/applications/graphstorecatalog/DefaultCatalogBusinessFacadeTest.java @@ -61,6 +61,7 @@ void shouldDetermineGraphExists() { null, null, null, + null, null ); @@ -101,6 +102,7 @@ void shouldDetermineGraphDoesNotExist() { null, null, null, + null, null ); @@ -145,6 +147,7 @@ void shouldValidateInputGraphName() { null, null, null, + null, null ); @@ -180,6 +183,7 @@ void shouldUseStrictValidationWhenProjecting() { null, null, null, + null, null ); @@ -250,6 +254,7 @@ void shouldHandleNullsInNativeProjectParameters() { null, null, null, + null, null ); @@ -345,6 +350,7 @@ void shouldHandleNullsInCypherProjectParameters() { null, null, null, + null, null ); @@ -438,6 +444,7 @@ void shouldDoExistenceCheckWhenProjecting() { null, null, null, + null, null ); @@ -519,6 +526,7 @@ void shouldDoPositiveExistenceCheckWhenProjectingSubGraph() { null, null, null, + null, null ); diff --git a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaCypherAggregation.java b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaCypherAggregation.java index 02a9cdd2eb..35dc41da1d 100644 --- a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaCypherAggregation.java +++ b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaCypherAggregation.java @@ -26,6 +26,7 @@ import org.neo4j.gds.compat.Neo4jProxy; import org.neo4j.gds.core.Username; import org.neo4j.gds.core.loading.Capabilities.WriteMode; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; @@ -104,6 +105,7 @@ public static CompatUserAggregationFunction newInstance() { @Override public CompatUserAggregator create(Context ctx) throws ProcedureException { var databaseService = Neo4jProxy.lookupComponentProvider(ctx, GraphDatabaseService.class, true); + var metricsFacade = Neo4jProxy.lookupComponentProvider(ctx, MetricsFacade.class, true); var username = Neo4jProxy.lookupComponentProvider(ctx, Username.class, true); var transaction = Neo4jProxy.lookupComponentProvider(ctx, Transaction.class, true); var queryProvider = ExecutingQueryProvider.fromTransaction(transaction); @@ -117,7 +119,8 @@ public CompatUserAggregator create(Context ctx) throws ProcedureException { DatabaseId.of(databaseService.databaseName()), username.username(), writeMode, - queryProvider + queryProvider, + metricsFacade.projectionMetrics() ); } } diff --git a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaGraphAggregator.java b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaGraphAggregator.java index 2a66d6f2c1..94737a42d6 100644 --- a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaGraphAggregator.java +++ b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/AlphaGraphAggregator.java @@ -21,6 +21,7 @@ import org.neo4j.gds.api.DatabaseId; import org.neo4j.gds.core.loading.Capabilities.WriteMode; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.values.AnyValue; @@ -36,9 +37,10 @@ public class AlphaGraphAggregator extends GraphAggregator { DatabaseId databaseId, String username, WriteMode writeMode, - ExecutingQueryProvider queryProvider + ExecutingQueryProvider queryProvider, + ProjectionMetricsService projectionMetricsService ) { - super(databaseId, username, writeMode, queryProvider); + super(databaseId, username, writeMode, queryProvider, projectionMetricsService); } @Override diff --git a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/CypherAggregation.java b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/CypherAggregation.java index 6aeb7187de..1061aee541 100644 --- a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/CypherAggregation.java +++ b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/CypherAggregation.java @@ -26,6 +26,7 @@ import org.neo4j.gds.compat.Neo4jProxy; import org.neo4j.gds.core.Username; import org.neo4j.gds.core.loading.Capabilities.WriteMode; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; @@ -103,6 +104,7 @@ public static CompatUserAggregationFunction newInstance() { @Override public CompatUserAggregator create(Context ctx) throws ProcedureException { var databaseService = Neo4jProxy.lookupComponentProvider(ctx, GraphDatabaseService.class, true); + var metricsFacade = Neo4jProxy.lookupComponentProvider(ctx, MetricsFacade.class, true); var username = Neo4jProxy.lookupComponentProvider(ctx, Username.class, true); var transaction = Neo4jProxy.lookupComponentProvider(ctx, Transaction.class, true); var queryProvider = ExecutingQueryProvider.fromTransaction(transaction); @@ -116,7 +118,8 @@ public CompatUserAggregator create(Context ctx) throws ProcedureException { DatabaseId.of(databaseService.databaseName()), username.username(), writeMode, - queryProvider + queryProvider, + metricsFacade.projectionMetrics() ); } } diff --git a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/GraphAggregator.java b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/GraphAggregator.java index afc5da6bd9..d34bcea739 100644 --- a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/GraphAggregator.java +++ b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/GraphAggregator.java @@ -32,6 +32,7 @@ import org.neo4j.gds.core.loading.construction.NodeLabelTokens; import org.neo4j.gds.core.loading.construction.PropertyValues; import org.neo4j.gds.core.utils.ProgressTimer; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.kernel.impl.util.ValueUtils; @@ -67,6 +68,7 @@ abstract class GraphAggregator implements CompatUserAggregator { private final String username; private final WriteMode writeMode; private final ExecutingQueryProvider queryProvider; + private final ProjectionMetricsService projectionMetricsService; private final ProgressTimer progressTimer; private final ConfigValidator configValidator; @@ -83,12 +85,14 @@ abstract class GraphAggregator implements CompatUserAggregator { DatabaseId databaseId, String username, WriteMode writeMode, - ExecutingQueryProvider queryProvider + ExecutingQueryProvider queryProvider, + ProjectionMetricsService projectionMetricsService ) { this.databaseId = databaseId; this.username = username; this.writeMode = writeMode; this.queryProvider = queryProvider; + this.projectionMetricsService = projectionMetricsService; this.progressTimer = ProgressTimer.start(); this.lock = new ReentrantLock(); this.configValidator = new ConfigValidator(); @@ -189,10 +193,13 @@ private static NodeLabelToken tryLabelsConfig(AnyValue nodeLabels, String nodeLa @Override public AnyValue result() throws ProcedureException { + var projectionMetric = projectionMetricsService.createCypherV2(); AggregationResult result; - try { + try(projectionMetric) { + projectionMetric.start(); result = buildGraph(); } catch (Exception e) { + projectionMetric.failed(); throw new ProcedureException( Status.Procedure.ProcedureCallFailed, e, diff --git a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/ProductGraphAggregator.java b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/ProductGraphAggregator.java index ea584fa0a7..477711a9ae 100644 --- a/cypher-aggregation/src/main/java/org/neo4j/gds/projection/ProductGraphAggregator.java +++ b/cypher-aggregation/src/main/java/org/neo4j/gds/projection/ProductGraphAggregator.java @@ -21,6 +21,7 @@ import org.neo4j.gds.api.DatabaseId; import org.neo4j.gds.core.loading.Capabilities.WriteMode; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.internal.kernel.api.exceptions.ProcedureException; import org.neo4j.kernel.api.exceptions.Status; import org.neo4j.values.AnyValue; @@ -34,9 +35,10 @@ public class ProductGraphAggregator extends GraphAggregator { DatabaseId databaseId, String username, WriteMode writeMode, - ExecutingQueryProvider queryProvider + ExecutingQueryProvider queryProvider, + ProjectionMetricsService projectionMetricsService ) { - super(databaseId, username, writeMode, queryProvider); + super(databaseId, username, writeMode, queryProvider, projectionMetricsService); } @Override diff --git a/cypher-aggregation/src/test/java/org/neo4j/gds/projection/ProductGraphAggregatorTest.java b/cypher-aggregation/src/test/java/org/neo4j/gds/projection/ProductGraphAggregatorTest.java index 834db60b7c..210cf6989d 100644 --- a/cypher-aggregation/src/test/java/org/neo4j/gds/projection/ProductGraphAggregatorTest.java +++ b/cypher-aggregation/src/test/java/org/neo4j/gds/projection/ProductGraphAggregatorTest.java @@ -23,6 +23,7 @@ import org.neo4j.gds.api.DatabaseId; import org.neo4j.gds.core.loading.Capabilities.WriteMode; import org.neo4j.gds.core.loading.GraphStoreCatalog; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.values.storable.NoValue; import org.neo4j.values.storable.Values; import org.neo4j.values.virtual.MapValue; @@ -41,7 +42,8 @@ void shouldImportHighNodeIds() { databaseId, userName, WriteMode.LOCAL, - ExecutingQueryProvider.empty() + ExecutingQueryProvider.empty(), + MetricsFacade.PASSTHROUGH_METRICS_FACADE.projectionMetrics() ); long source = 1L << 50; diff --git a/executor/src/main/java/org/neo4j/gds/executor/ExecutionContext.java b/executor/src/main/java/org/neo4j/gds/executor/ExecutionContext.java index 577b86c8be..42844faa2d 100644 --- a/executor/src/main/java/org/neo4j/gds/executor/ExecutionContext.java +++ b/executor/src/main/java/org/neo4j/gds/executor/ExecutionContext.java @@ -37,8 +37,7 @@ import org.neo4j.gds.core.write.NodePropertyExporterBuilder; import org.neo4j.gds.core.write.RelationshipExporterBuilder; import org.neo4j.gds.core.write.RelationshipStreamExporterBuilder; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.logging.Log; import org.neo4j.logging.NullLog; @@ -72,7 +71,7 @@ public interface ExecutionContext { boolean isGdsAdmin(); - AlgorithmMetricsService algorithmMetricsService(); + MetricsFacade metricsFacade(); @Nullable RelationshipStreamExporterBuilder relationshipStreamExporterBuilder(); @@ -178,8 +177,9 @@ public boolean isGdsAdmin() { } @Override - public AlgorithmMetricsService algorithmMetricsService() { - return new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()); + public MetricsFacade metricsFacade() { + return MetricsFacade.PASSTHROUGH_METRICS_FACADE; + } @Override diff --git a/executor/src/main/java/org/neo4j/gds/executor/ProcedureExecutor.java b/executor/src/main/java/org/neo4j/gds/executor/ProcedureExecutor.java index e5afa0b596..18ae4901ad 100644 --- a/executor/src/main/java/org/neo4j/gds/executor/ProcedureExecutor.java +++ b/executor/src/main/java/org/neo4j/gds/executor/ProcedureExecutor.java @@ -112,7 +112,7 @@ public RESULT compute( algo.getProgressTracker().setEstimatedResourceFootprint(memoryEstimationInBytes, config.concurrency()); - ALGO_RESULT result = executeAlgorithm(builder, algo, executionContext.algorithmMetricsService()); + ALGO_RESULT result = executeAlgorithm(builder, algo, executionContext.metricsFacade().algorithmMetrics()); var computationResult = builder .graph(graph) diff --git a/executor/src/test/java/org/neo4j/gds/executor/MemoryEstimationExecutorTest.java b/executor/src/test/java/org/neo4j/gds/executor/MemoryEstimationExecutorTest.java index f80f58a933..13b27d2988 100644 --- a/executor/src/test/java/org/neo4j/gds/executor/MemoryEstimationExecutorTest.java +++ b/executor/src/test/java/org/neo4j/gds/executor/MemoryEstimationExecutorTest.java @@ -42,8 +42,7 @@ import org.neo4j.gds.core.utils.progress.EmptyTaskRegistryFactory; import org.neo4j.gds.core.utils.warnings.EmptyUserLogRegistryFactory; import org.neo4j.gds.gdl.GdlGraphs; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.projection.GraphProjectFromStoreConfig; import org.neo4j.gds.test.TestAlgorithm; import org.neo4j.gds.test.TestAlgorithmResult; @@ -87,7 +86,7 @@ void setup() throws Exception { .nodeLookup(NodeLookup.EMPTY) .modelCatalog(ModelCatalog.EMPTY) .isGdsAdmin(false) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); memoryEstimationExecutor = new MemoryEstimationExecutor<>( diff --git a/executor/src/test/java/org/neo4j/gds/executor/ProcedureExecutorTest.java b/executor/src/test/java/org/neo4j/gds/executor/ProcedureExecutorTest.java index b8edfa560d..59fa241076 100644 --- a/executor/src/test/java/org/neo4j/gds/executor/ProcedureExecutorTest.java +++ b/executor/src/test/java/org/neo4j/gds/executor/ProcedureExecutorTest.java @@ -41,8 +41,7 @@ import org.neo4j.gds.extension.GdlExtension; import org.neo4j.gds.extension.GdlGraph; import org.neo4j.gds.extension.Inject; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.utils.StringJoining; import java.util.HashSet; @@ -138,7 +137,7 @@ private ExecutionContext executionContext(TaskStore taskStore) { .algorithmMetaDataSetter(AlgorithmMetaDataSetter.EMPTY) .nodeLookup(NodeLookup.EMPTY) .userLogRegistryFactory(EmptyUserLogRegistryFactory.INSTANCE) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); } diff --git a/metrics-api/src/main/java/org/neo4j/gds/metrics/MetricsFacade.java b/metrics-api/src/main/java/org/neo4j/gds/metrics/MetricsFacade.java new file mode 100644 index 0000000000..9b6cebb651 --- /dev/null +++ b/metrics-api/src/main/java/org/neo4j/gds/metrics/MetricsFacade.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) "Neo4j" + * Neo4j Sweden AB [http://neo4j.com] + * + * This file is part of Neo4j. + * + * Neo4j is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.neo4j.gds.metrics; + +import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; + +public class MetricsFacade { + + public static final MetricsFacade PASSTHROUGH_METRICS_FACADE = new MetricsFacade( + new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()), + new ProjectionMetricsService(new PassthroughExecutionMetricRegistrar()) + ); + + private final AlgorithmMetricsService algorithmMetricsService; + private final ProjectionMetricsService projectionMetricsService; + + public MetricsFacade( + AlgorithmMetricsService algorithmMetricsService, + ProjectionMetricsService projectionMetricsService + ){ + this.algorithmMetricsService = algorithmMetricsService; + this.projectionMetricsService = projectionMetricsService; + } + + public AlgorithmMetricsService algorithmMetrics(){ + return algorithmMetricsService; + } + public ProjectionMetricsService projectionMetrics(){ + return projectionMetricsService; + } +} diff --git a/pipeline/src/test/java/org/neo4j/gds/ml/pipeline/linkPipeline/LinkPredictionTrainingPipelineTest.java b/pipeline/src/test/java/org/neo4j/gds/ml/pipeline/linkPipeline/LinkPredictionTrainingPipelineTest.java index febba45311..fecb323add 100644 --- a/pipeline/src/test/java/org/neo4j/gds/ml/pipeline/linkPipeline/LinkPredictionTrainingPipelineTest.java +++ b/pipeline/src/test/java/org/neo4j/gds/ml/pipeline/linkPipeline/LinkPredictionTrainingPipelineTest.java @@ -42,8 +42,7 @@ import org.neo4j.gds.executor.ExecutionContext; import org.neo4j.gds.executor.GdsCallableFinder; import org.neo4j.gds.executor.ImmutableExecutionContext; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.ml.api.TrainingMethod; import org.neo4j.gds.ml.models.automl.TunableTrainerConfig; import org.neo4j.gds.ml.models.logisticregression.LogisticRegressionTrainConfig; @@ -197,7 +196,7 @@ void deriveRelationshipWeightProperty() { .taskRegistryFactory(EmptyTaskRegistryFactory.INSTANCE) .userLogRegistryFactory(EmptyUserLogRegistryFactory.INSTANCE) .isGdsAdmin(false) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); var pipeline = new LinkPredictionTrainingPipeline(); @@ -242,7 +241,7 @@ void deriveRelationshipWeightPropertyFromTrainedModel() { .taskRegistryFactory(EmptyTaskRegistryFactory.INSTANCE) .userLogRegistryFactory(EmptyUserLogRegistryFactory.INSTANCE) .isGdsAdmin(false) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); var pipeline = new LinkPredictionTrainingPipeline(); @@ -287,7 +286,7 @@ void notDerivePropertyFromUnweightedTrainedModel() { .taskRegistryFactory(EmptyTaskRegistryFactory.INSTANCE) .userLogRegistryFactory(EmptyUserLogRegistryFactory.INSTANCE) .isGdsAdmin(false) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); var pipeline = new LinkPredictionTrainingPipeline(); diff --git a/proc/common/src/main/java/org/neo4j/gds/BaseProc.java b/proc/common/src/main/java/org/neo4j/gds/BaseProc.java index ced7901acf..a4b44f2e84 100644 --- a/proc/common/src/main/java/org/neo4j/gds/BaseProc.java +++ b/proc/common/src/main/java/org/neo4j/gds/BaseProc.java @@ -31,7 +31,7 @@ import org.neo4j.gds.executor.ExecutionContext; import org.neo4j.gds.executor.GraphStoreFromCatalogLoader; import org.neo4j.gds.executor.ImmutableExecutionContext; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.transaction.DatabaseTransactionContext; import org.neo4j.gds.transaction.EmptyTransactionContext; import org.neo4j.gds.transaction.TransactionContext; @@ -77,7 +77,7 @@ public abstract class BaseProc { public Username username = Username.EMPTY_USERNAME; @Context - public AlgorithmMetricsService algorithmMetricsService; + public MetricsFacade metricsFacade; protected String username() { return username.username(); @@ -161,7 +161,7 @@ public ExecutionContext executionContext() { .algorithmMetaDataSetter(new TransactionAlgorithmMetaDataSetter(transaction)) .nodeLookup(new TransactionNodeLookup(transaction)) .isGdsAdmin(transactionContext().isGdsAdmin()) - .algorithmMetricsService(algorithmMetricsService) + .metricsFacade(metricsFacade) .build(); } diff --git a/proc/common/src/test/java/org/neo4j/gds/MutatePropertyComputationResultConsumerTest.java b/proc/common/src/test/java/org/neo4j/gds/MutatePropertyComputationResultConsumerTest.java index bb231c388e..8aee6474e9 100644 --- a/proc/common/src/test/java/org/neo4j/gds/MutatePropertyComputationResultConsumerTest.java +++ b/proc/common/src/test/java/org/neo4j/gds/MutatePropertyComputationResultConsumerTest.java @@ -49,8 +49,7 @@ import org.neo4j.gds.extension.GdlGraph; import org.neo4j.gds.extension.Inject; import org.neo4j.gds.gdl.GdlFactory; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.nodeproperties.IdentityPropertyValues; import org.neo4j.gds.test.ImmutableTestMutateConfig; import org.neo4j.gds.test.TestAlgoResultBuilder; @@ -90,7 +89,7 @@ class MutatePropertyComputationResultConsumerTest { .nodeLookup(NodeLookup.EMPTY) .modelCatalog(ModelCatalog.EMPTY) .isGdsAdmin(false) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); @BeforeEach diff --git a/proc/common/src/test/java/org/neo4j/gds/WriteNodePropertiesComputationResultConsumerTest.java b/proc/common/src/test/java/org/neo4j/gds/WriteNodePropertiesComputationResultConsumerTest.java index 6f974f5cc2..1a52c4cb74 100644 --- a/proc/common/src/test/java/org/neo4j/gds/WriteNodePropertiesComputationResultConsumerTest.java +++ b/proc/common/src/test/java/org/neo4j/gds/WriteNodePropertiesComputationResultConsumerTest.java @@ -58,8 +58,7 @@ import org.neo4j.gds.extension.GdlExtension; import org.neo4j.gds.extension.GdlGraph; import org.neo4j.gds.extension.Inject; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.test.ImmutableTestWriteConfig; import org.neo4j.gds.test.TestAlgoResultBuilder; import org.neo4j.gds.test.TestAlgorithm; @@ -98,7 +97,7 @@ class WriteNodePropertiesComputationResultConsumerTest extends BaseTest { .modelCatalog(ModelCatalog.EMPTY) .isGdsAdmin(false) .nodePropertyExporterBuilder(new NativeNodePropertiesExporterBuilder(EmptyTransactionContext.INSTANCE)) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); @Test diff --git a/proc/common/src/test/java/org/neo4j/gds/WriteProcCancellationTest.java b/proc/common/src/test/java/org/neo4j/gds/WriteProcCancellationTest.java index dc80f4a763..bb873b864d 100644 --- a/proc/common/src/test/java/org/neo4j/gds/WriteProcCancellationTest.java +++ b/proc/common/src/test/java/org/neo4j/gds/WriteProcCancellationTest.java @@ -41,8 +41,7 @@ import org.neo4j.gds.gdl.GdlFactory; import org.neo4j.gds.gdl.GdlGraphs; import org.neo4j.gds.gdl.ImmutableGraphProjectFromGdlConfig; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.test.TestAlgoResultBuilder; import org.neo4j.gds.test.TestAlgorithm; import org.neo4j.gds.test.TestAlgorithmResult; @@ -126,7 +125,7 @@ public long nodeCount() { .modelCatalog(ModelCatalog.EMPTY) .isGdsAdmin(false) .nodePropertyExporterBuilder(new NativeNodePropertiesExporterBuilder(DatabaseTransactionContext.of(db, tx))) - .algorithmMetricsService(new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar())) + .metricsFacade(MetricsFacade.PASSTHROUGH_METRICS_FACADE) .build(); assertThatThrownBy(() -> resultConsumer.consume(computationResult, executionContext)) diff --git a/proc/pregel/src/test/java/org/neo4j/gds/pregel/proc/PregelProcTest.java b/proc/pregel/src/test/java/org/neo4j/gds/pregel/proc/PregelProcTest.java index d90aefff0e..f0a2869019 100644 --- a/proc/pregel/src/test/java/org/neo4j/gds/pregel/proc/PregelProcTest.java +++ b/proc/pregel/src/test/java/org/neo4j/gds/pregel/proc/PregelProcTest.java @@ -56,8 +56,7 @@ import org.neo4j.gds.executor.ExecutionContext; import org.neo4j.gds.executor.NewConfigFunction; import org.neo4j.gds.executor.ProcedureExecutor; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.internal.kernel.api.procs.ProcedureCallContext; import org.neo4j.logging.NullLog; import org.neo4j.procedure.Context; @@ -212,7 +211,7 @@ void cleanupTaskRegistryWhenTheAlgorithmFailsInStreamMode() { proc.log = NullLog.getInstance(); proc.callContext = ProcedureCallContext.EMPTY; - proc.algorithmMetricsService = new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()); + proc.metricsFacade = MetricsFacade.PASSTHROUGH_METRICS_FACADE; Map config = Map.of( "maxIterations", 20, @@ -240,7 +239,7 @@ void cleanupTaskRegistryWhenTheAlgorithmFailsInWriteMode() { proc.log = NullLog.getInstance(); proc.callContext = ProcedureCallContext.EMPTY; - proc.algorithmMetricsService = new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()); + proc.metricsFacade = MetricsFacade.PASSTHROUGH_METRICS_FACADE; Map config = Map.of( "maxIterations", 20, @@ -267,7 +266,7 @@ void cleanupTaskRegistryWhenTheAlgorithmFailsInMutateMode() { proc.log = NullLog.getInstance(); proc.callContext = ProcedureCallContext.EMPTY; - proc.algorithmMetricsService = new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()); + proc.metricsFacade = MetricsFacade.PASSTHROUGH_METRICS_FACADE; Map config = Map.of( "maxIterations", 20, diff --git a/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java b/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java index 7e9596b7fc..6e8ce0f755 100644 --- a/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java +++ b/proc/test/src/main/java/org/neo4j/gds/ProcedureRunner.java @@ -24,8 +24,7 @@ import org.neo4j.gds.core.utils.progress.TaskRegistryFactory; import org.neo4j.gds.core.utils.warnings.EmptyUserLogRegistryFactory; import org.neo4j.gds.core.utils.warnings.UserLogRegistryFactory; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Transaction; import org.neo4j.internal.kernel.api.procs.ProcedureCallContext; @@ -46,7 +45,7 @@ public static

P instantiateProcedure( UserLogRegistryFactory userLogRegistryFactory, Transaction tx, Username username, - AlgorithmMetricsService algorithmMetricsService + MetricsFacade metricsFacade ) { P proc; try { @@ -64,7 +63,7 @@ public static

P instantiateProcedure( proc.userLogRegistryFactory = userLogRegistryFactory; proc.username = username; - proc.algorithmMetricsService = algorithmMetricsService; + proc.metricsFacade = metricsFacade; return proc; } @@ -88,7 +87,7 @@ public static

P applyOnProcedure( EmptyUserLogRegistryFactory.INSTANCE, tx, username, - new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()) + MetricsFacade.PASSTHROUGH_METRICS_FACADE ); func.accept(proc); return proc; diff --git a/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java b/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java index 25998d7fd3..8e9627c047 100644 --- a/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java +++ b/procedures/extension/src/main/java/org/neo4j/gds/extension/OpenGraphDataScienceExtension.java @@ -23,8 +23,10 @@ import org.neo4j.configuration.Config; import org.neo4j.gds.applications.graphstorecatalog.CatalogBusinessFacade; import org.neo4j.gds.core.write.NativeExportBuildersProvider; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.procedures.GraphDataScience; import org.neo4j.gds.procedures.integration.ExporterBuildersProviderService; import org.neo4j.gds.procedures.integration.ExtensionBuilder; @@ -67,19 +69,21 @@ public Lifecycle newInstance(ExtensionContext extensionContext, Dependencies dep Optional> businessFacadeDecorator = Optional.empty(); var algorithmMetricsService = new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()); + var projectionMetricsService = new ProjectionMetricsService(new PassthroughExecutionMetricRegistrar()); + var metricsFacade = MetricsFacade.PASSTHROUGH_METRICS_FACADE; extensionBuilder .withComponent( GraphDataScience.class, () -> extensionBuilder.gdsProvider( exporterBuildersProviderService, businessFacadeDecorator, - algorithmMetricsService + metricsFacade ) ) .withComponent( - AlgorithmMetricsService.class, - () -> ctx -> algorithmMetricsService + MetricsFacade.class, + () -> ctx -> metricsFacade ) .registerExtension(); diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProvider.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProvider.java index 97170d8d73..ef12492e70 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProvider.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProvider.java @@ -48,6 +48,7 @@ import org.neo4j.gds.core.loading.GraphStoreCatalogService; import org.neo4j.gds.core.write.ExporterContext; import org.neo4j.gds.logging.Log; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.procedures.KernelTransactionAccessor; import org.neo4j.gds.procedures.ProcedureTransactionAccessor; import org.neo4j.gds.procedures.TaskRegistryFactoryService; @@ -114,6 +115,8 @@ public class CatalogFacadeProvider { // Business logic private final Optional> businessFacadeDecorator; + private final ProjectionMetricsService projectionMetricsService; + /** * We inject services here so that we may control and isolate access to dependencies. * Take {@link org.neo4j.gds.services.UserAccessor} for example. @@ -154,7 +157,8 @@ public class CatalogFacadeProvider { WriteNodePropertiesApplication writeNodePropertiesApplication, WriteRelationshipPropertiesApplication writeRelationshipPropertiesApplication, WriteRelationshipsApplication writeRelationshipsApplication, - Optional> businessFacadeDecorator + Optional> businessFacadeDecorator, + ProjectionMetricsService projectionMetricsService ) { this.catalogConfigurationService = catalogConfigurationService; this.graphNameValidationService = graphNameValidationService; @@ -193,6 +197,8 @@ public class CatalogFacadeProvider { this.writeRelationshipsApplication = writeRelationshipsApplication; this.businessFacadeDecorator = businessFacadeDecorator; + + this.projectionMetricsService = projectionMetricsService; } /** @@ -262,7 +268,8 @@ public void accept(AutoCloseable autoCloseable) { writeNodePropertiesApplication, writeRelationshipPropertiesApplication, writeNodeLabelApplication, - writeRelationshipsApplication + writeRelationshipsApplication, + projectionMetricsService ); // wrap in decorator to inject conditional behaviour diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProviderFactory.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProviderFactory.java index 20b7dbcff2..da8d113867 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProviderFactory.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/CatalogFacadeProviderFactory.java @@ -47,6 +47,7 @@ import org.neo4j.gds.core.loading.GraphProjectCypherResult; import org.neo4j.gds.core.loading.GraphStoreCatalogService; import org.neo4j.gds.logging.Log; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.procedures.KernelTransactionAccessor; import org.neo4j.gds.procedures.ProcedureTransactionAccessor; import org.neo4j.gds.procedures.TaskRegistryFactoryService; @@ -84,6 +85,7 @@ CatalogFacadeProvider createCatalogFacadeProvider( DatabaseIdAccessor databaseIdAccessor, KernelTransactionAccessor kernelTransactionAccessor, TaskRegistryFactoryService taskRegistryFactoryService, + ProjectionMetricsService projectionMetricsService, TerminationFlagService terminationFlagService, UserLogServices userLogServices, UserAccessor userServices @@ -170,7 +172,8 @@ CatalogFacadeProvider createCatalogFacadeProvider( writeNodePropertiesApplication, writeRelationshipPropertiesApplication, writeRelationshipsApplication, - businessFacadeDecorator + businessFacadeDecorator, + projectionMetricsService ); } } diff --git a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExtensionBuilder.java b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExtensionBuilder.java index ae18dc4f4e..f7af068b84 100644 --- a/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExtensionBuilder.java +++ b/procedures/integration/src/main/java/org/neo4j/gds/procedures/integration/ExtensionBuilder.java @@ -29,7 +29,8 @@ import org.neo4j.gds.core.utils.warnings.UserLogRegistryFactory; import org.neo4j.gds.internal.MemoryEstimationSettings; import org.neo4j.gds.logging.Log; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; +import org.neo4j.gds.metrics.MetricsFacade; +import org.neo4j.gds.metrics.projections.ProjectionMetricsService; import org.neo4j.gds.procedures.GraphDataScience; import org.neo4j.gds.procedures.KernelTransactionAccessor; import org.neo4j.gds.procedures.TaskRegistryFactoryService; @@ -188,26 +189,31 @@ public void registerExtension() { * * @param exporterBuildersProviderService The catalog of writers * @param businessFacadeDecorator Any checks added across requests - * @param algorithmMetricsService + * @param metricsFacade */ public ThrowingFunction gdsProvider( ExporterBuildersProviderService exporterBuildersProviderService, Optional> businessFacadeDecorator, - AlgorithmMetricsService algorithmMetricsService + MetricsFacade metricsFacade ) { var catalogFacadeProvider = createCatalogFacadeProvider( exporterBuildersProviderService, - businessFacadeDecorator + businessFacadeDecorator, + metricsFacade.projectionMetrics() ); - var communityProcedureProvider = createCommunityProcedureProvider(exporterBuildersProviderService, algorithmMetricsService); + var communityProcedureProvider = createCommunityProcedureProvider( + exporterBuildersProviderService, + metricsFacade + ); return new GraphDataScienceProvider(log, catalogFacadeProvider, communityProcedureProvider); } private CatalogFacadeProvider createCatalogFacadeProvider( ExporterBuildersProviderService exporterBuildersProviderService, - Optional> businessFacadeDecorator + Optional> businessFacadeDecorator, + ProjectionMetricsService projectionMetricsService ) { var catalogFacadeProviderFactory = new CatalogFacadeProviderFactory( log, @@ -220,6 +226,7 @@ private CatalogFacadeProvider createCatalogFacadeProvider( databaseIdAccessor, kernelTransactionAccessor, taskRegistryFactoryService, + projectionMetricsService, terminationFlagService, userLogServices, userAccessor @@ -227,7 +234,7 @@ private CatalogFacadeProvider createCatalogFacadeProvider( } private CommunityProcedureProvider createCommunityProcedureProvider(ExporterBuildersProviderService exporterBuildersProviderService, - AlgorithmMetricsService algorithmMetricsService + MetricsFacade metricsFacade ) { var algorithmMetaDataSetterService = new AlgorithmMetaDataSetterService(); @@ -243,7 +250,7 @@ private CommunityProcedureProvider createCommunityProcedureProvider(ExporterBuil terminationFlagService, userLogServices, userAccessor, - algorithmMetricsService + metricsFacade.algorithmMetrics() ); } } diff --git a/test-utils/src/main/java/org/neo4j/gds/BaseTest.java b/test-utils/src/main/java/org/neo4j/gds/BaseTest.java index 970382e1f6..e43a791deb 100644 --- a/test-utils/src/main/java/org/neo4j/gds/BaseTest.java +++ b/test-utils/src/main/java/org/neo4j/gds/BaseTest.java @@ -31,8 +31,7 @@ import org.neo4j.gds.extension.Inject; import org.neo4j.gds.extension.Neo4jGraphExtension; import org.neo4j.gds.extension.NodeFunction; -import org.neo4j.gds.metrics.algorithms.AlgorithmMetricsService; -import org.neo4j.gds.metrics.PassthroughExecutionMetricRegistrar; +import org.neo4j.gds.metrics.MetricsFacade; import org.neo4j.graphdb.GraphDatabaseService; import org.neo4j.graphdb.Node; import org.neo4j.graphdb.Result; @@ -99,8 +98,8 @@ protected void configuration(TestDatabaseManagementServiceBuilder builder) { @Override public Lifecycle newInstance(ExtensionContext context, Dependencies dependencies) { dependencies.globalProcedures().registerComponent( - AlgorithmMetricsService.class, - ctx -> new AlgorithmMetricsService(new PassthroughExecutionMetricRegistrar()), + MetricsFacade.class, + ctx -> MetricsFacade.PASSTHROUGH_METRICS_FACADE, false ); return new LifecycleAdapter();