Skip to content

Commit 7520175

Browse files
Merge pull request #9848 from IoannisPanagiotas/memory-tracking-reporting
Memory listing procedures
2 parents 8385df9 + 689efef commit 7520175

File tree

32 files changed

+1079
-53
lines changed

32 files changed

+1079
-53
lines changed

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/ComputationService.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ class ComputationService {
3434
private final Log log;
3535
private final MemoryGuard memoryGuard;
3636
private final AlgorithmMetricsService algorithmMetricsService;
37+
private final String username;
3738

38-
ComputationService(Log log, MemoryGuard memoryGuard, AlgorithmMetricsService algorithmMetricsService) {
39+
ComputationService(String username,Log log, MemoryGuard memoryGuard, AlgorithmMetricsService algorithmMetricsService) {
3940
this.log = log;
4041
this.memoryGuard = memoryGuard;
4142
this.algorithmMetricsService = algorithmMetricsService;
43+
this.username = username;
4244
}
4345

4446
<CONFIGURATION extends AlgoBaseConfig, RESULT_FROM_ALGORITHM> RESULT_FROM_ALGORITHM computeAlgorithm(
@@ -49,7 +51,7 @@ <CONFIGURATION extends AlgoBaseConfig, RESULT_FROM_ALGORITHM> RESULT_FROM_ALGORI
4951
Computation<RESULT_FROM_ALGORITHM> computation,
5052
DimensionTransformer dimensionTransformer
5153
) {
52-
memoryGuard.assertAlgorithmCanRun(estimationSupplier, graphResources.graphStore(), configuration, label, dimensionTransformer);
54+
memoryGuard.assertAlgorithmCanRun(username,estimationSupplier, graphResources.graphStore(), configuration, label, dimensionTransformer);
5355

5456
return computeWithMetrics(graphResources, label, computation);
5557
}

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultAlgorithmProcessingTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ public static DefaultAlgorithmProcessingTemplate create(
5757
MemoryGuard memoryGuard,
5858
RequestScopedDependencies requestScopedDependencies
5959
) {
60-
var algorithmComputer = new ComputationService(log, memoryGuard, algorithmMetricsService);
60+
var algorithmComputer = new ComputationService(requestScopedDependencies.getUser().getUsername(),log, memoryGuard, algorithmMetricsService);
6161

6262
return new DefaultAlgorithmProcessingTemplate(
6363
graphStoreCatalogService,

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/DefaultMemoryGuard.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ public static DefaultMemoryGuard create(
6161

6262
@Override
6363
public synchronized <CONFIGURATION extends AlgoBaseConfig> void assertAlgorithmCanRun(
64+
String username,
6465
Supplier<MemoryEstimation> estimationFactory,
6566
GraphStore graphStore,
6667
CONFIGURATION configuration,
@@ -80,11 +81,11 @@ public synchronized <CONFIGURATION extends AlgoBaseConfig> void assertAlgorithmC
8081

8182
var bytesToReserve = memoryRequirement.requiredMemory();
8283
if (configuration.sudo()) {
83-
memoryTracker.track(configuration.jobId(), bytesToReserve);
84+
memoryTracker.track(username,label.asString(), configuration.jobId(), bytesToReserve);
8485
return;
8586
}
8687

87-
memoryTracker.tryToTrack(configuration.jobId(), bytesToReserve);
88+
memoryTracker.tryToTrack(username, label.asString(), configuration.jobId(), bytesToReserve);
8889

8990
} catch (MemoryEstimationNotImplementedException e) {
9091
log.info("Memory usage estimate not available for " + label + ", skipping guard");

applications/algorithms/machinery/src/main/java/org/neo4j/gds/applications/algorithms/machinery/MemoryGuard.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ public interface MemoryGuard {
3535
MemoryGuard DISABLED = new MemoryGuard() {
3636
@Override
3737
public <CONFIGURATION extends AlgoBaseConfig> void assertAlgorithmCanRun(
38+
String username,
3839
Supplier<MemoryEstimation> estimationFactory,
3940
GraphStore graphStore,
4041
CONFIGURATION configuration,
4142
Label label,
4243
DimensionTransformer dimensionTransformer
4344
) {
44-
// do nothing
4545
}
4646
};
4747

@@ -51,6 +51,7 @@ public <CONFIGURATION extends AlgoBaseConfig> void assertAlgorithmCanRun(
5151
* @throws IllegalStateException when there is not enough memory available to run the algorithm in the given configuration on the given graph
5252
*/
5353
<CONFIGURATION extends AlgoBaseConfig> void assertAlgorithmCanRun(
54+
String username,
5455
Supplier<MemoryEstimation> estimationFactory,
5556
GraphStore graphStore,
5657
CONFIGURATION configuration,

applications/algorithms/machinery/src/test/java/org/neo4j/gds/applications/algorithms/machinery/DefaultMemoryGuardTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import org.junit.jupiter.api.Test;
2323
import org.neo4j.gds.api.GraphStore;
24+
import org.neo4j.gds.api.User;
2425
import org.neo4j.gds.applications.services.GraphDimensionFactory;
2526
import org.neo4j.gds.core.GraphDimensions;
2627
import org.neo4j.gds.core.concurrency.Concurrency;
@@ -67,7 +68,8 @@ void shouldAllowExecution() {
6768

6869
// there is enough memory available
6970
memoryGuard.assertAlgorithmCanRun(
70-
() -> memoryEstimation,
71+
User.DEFAULT.getUsername(),
72+
()-> memoryEstimation,
7173
graphStore,
7274
configuration,
7375
new StandardLabel("some label"),
@@ -97,6 +99,7 @@ void shouldGuardExecutionUsingMinimumEstimate() {
9799
// uh oh
98100
try {
99101
memoryGuard.assertAlgorithmCanRun(
102+
User.DEFAULT.getUsername(),
100103
() -> memoryEstimation,
101104
graphStore,
102105
configuration,
@@ -132,6 +135,7 @@ void shouldGuardExecutionUsingMaximumEstimate() {
132135
// uh oh
133136
try {
134137
memoryGuard.assertAlgorithmCanRun(
138+
User.DEFAULT.getUsername(),
135139
() -> memoryEstimation,
136140
graphStore,
137141
configuration,
@@ -166,6 +170,7 @@ void shouldRespectSudoFlag() {
166170
when(memoryTree.memoryUsage()).thenReturn(MemoryRange.of(43, 99));
167171

168172
assertThatIllegalStateException().isThrownBy(() -> memoryGuard.assertAlgorithmCanRun(
173+
User.DEFAULT.getUsername(),
169174
() -> memoryEstimation,
170175
graphStore,
171176
new ExampleConfiguration(false),
@@ -175,6 +180,7 @@ void shouldRespectSudoFlag() {
175180

176181
// now with sudo
177182
assertDoesNotThrow(() -> memoryGuard.assertAlgorithmCanRun(
183+
User.DEFAULT.getUsername(),
178184
() -> memoryEstimation,
179185
graphStore,
180186
new ExampleConfiguration(true),

applications/graph-store-catalog/src/integrationTest/java/org/neo4j/gds/applications/graphstorecatalog/MemoryUsageValidatorTest.java

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,12 @@ void shouldPassOnSufficientMemory() {
5555
var dimensions = GraphDimensions.builder().nodeCount(1000).build();
5656
var memoryTree = MemoryTree.empty();
5757

58-
assertThatNoException().isThrownBy(() -> new MemoryUsageValidator(new MemoryTracker(10000000, Log.noOpLog()),
58+
assertThatNoException().isThrownBy(() -> new MemoryUsageValidator("foo",new MemoryTracker(10000000, Log.noOpLog()),
5959
false,
6060
Log.noOpLog()
6161
)
6262
.tryValidateMemoryUsage(
63+
"task",
6364
TestConfig.empty(),
6465
(config) -> new MemoryTreeWithDimensions(memoryTree, dimensions)
6566
));
@@ -70,11 +71,12 @@ void shouldFailOnInsufficientMemory() {
7071
var dimensions = GraphDimensions.builder().nodeCount(1000).build();
7172
var memoryTree = new TestTree("test", MemoryRange.of(42));
7273

73-
assertThatThrownBy(() -> new MemoryUsageValidator(new MemoryTracker(21, Log.noOpLog()),
74+
assertThatThrownBy(() -> new MemoryUsageValidator("foo", new MemoryTracker(21, Log.noOpLog()),
7475
false,
7576
Log.noOpLog()
7677
)
7778
.tryValidateMemoryUsage(
79+
"task",
7880
TestConfig.empty(),
7981
(config) -> new MemoryTreeWithDimensions(memoryTree, dimensions)
8082
))
@@ -87,11 +89,12 @@ void shouldNotFailOnInsufficientMemoryIfInSudoMode() {
8789
var dimensions = GraphDimensions.builder().nodeCount(1000).build();
8890
var memoryTree = new TestTree("test", MemoryRange.of(42));
8991

90-
assertThatNoException().isThrownBy(() -> new MemoryUsageValidator(new MemoryTracker(21, Log.noOpLog()),
92+
assertThatNoException().isThrownBy(() -> new MemoryUsageValidator("foo", new MemoryTracker(21, Log.noOpLog()),
9193
false,
9294
Log.noOpLog()
9395
)
9496
.tryValidateMemoryUsage(
97+
"task",
9598
TestConfig.of(CypherMapWrapper.empty().withBoolean("sudo", true)),
9699
(config) -> new MemoryTreeWithDimensions(memoryTree, dimensions)
97100
));
@@ -103,11 +106,15 @@ void shouldLogWhenFailing() {
103106
var dimensions = GraphDimensions.builder().nodeCount(1000).build();
104107
var memoryTree = new TestTree("test", MemoryRange.of(42));
105108
var memoryUsageValidator = new MemoryUsageValidator(
106-
new MemoryTracker(21, log), false, log
109+
"foo",
110+
new MemoryTracker(21, log),
111+
false,
112+
log
107113
);
108114

109115
assertThatIllegalStateException().isThrownBy(
110116
() -> memoryUsageValidator.tryValidateMemoryUsage(
117+
"task",
111118
TestConfig.of(CypherMapWrapper.empty()),
112119
(config -> new MemoryTreeWithDimensions(memoryTree, dimensions))
113120
)
@@ -140,6 +147,7 @@ static Stream<Arguments> input() {
140147
void doesNotThrow(MemoryEstimation estimation, boolean useMaxMemoryUsage) {
141148
var memoryTrackerMock = mock(MemoryTracker.class);
142149
var memoryUsageValidator = new MemoryUsageValidator(
150+
"foo",
143151
memoryTrackerMock,
144152
false,
145153
Log.noOpLog()
@@ -148,6 +156,7 @@ void doesNotThrow(MemoryEstimation estimation, boolean useMaxMemoryUsage) {
148156
var memoryTreeWithDimensions = new MemoryTreeWithDimensions(memoryTree, TEST_DIMENSIONS);
149157

150158
assertDoesNotThrow(() -> memoryUsageValidator.validateMemoryUsage(
159+
"task",
151160
memoryTreeWithDimensions.memoryTree.memoryUsage(), 10_000,
152161
useMaxMemoryUsage,
153162
new JobId("foo"), Log.noOpLog()
@@ -158,6 +167,7 @@ void doesNotThrow(MemoryEstimation estimation, boolean useMaxMemoryUsage) {
158167
@MethodSource("input")
159168
void throwsOnMinUsageExceeded(MemoryEstimation estimation, boolean ignored) {
160169
var memoryUsageValidator = new MemoryUsageValidator(
170+
"foo",
161171
null,
162172
false,
163173
Log.noOpLog()
@@ -167,6 +177,7 @@ void throwsOnMinUsageExceeded(MemoryEstimation estimation, boolean ignored) {
167177
var memoryTreeWithDimensions = new MemoryTreeWithDimensions(memoryTree, TEST_DIMENSIONS);
168178

169179
assertThatThrownBy(() -> memoryUsageValidator.validateMemoryUsage(
180+
"task",
170181
memoryTreeWithDimensions.memoryTree.memoryUsage(), 1,
171182
false,
172183
new JobId("foo"), Log.noOpLog()
@@ -179,6 +190,7 @@ void throwsOnMinUsageExceeded(MemoryEstimation estimation, boolean ignored) {
179190
@MethodSource("input")
180191
void throwsOnMaxUsageExceeded(MemoryEstimation estimation, boolean ignored) {
181192
var memoryUsageValidator = new MemoryUsageValidator(
193+
"foo",
182194
null,
183195
false,
184196
Log.noOpLog()
@@ -188,7 +200,9 @@ void throwsOnMaxUsageExceeded(MemoryEstimation estimation, boolean ignored) {
188200
var memoryTreeWithDimensions = new MemoryTreeWithDimensions(memoryTree, TEST_DIMENSIONS);
189201

190202
assertThatThrownBy(() -> memoryUsageValidator.validateMemoryUsage(
191-
memoryTreeWithDimensions.memoryTree.memoryUsage(), 1,
203+
"task",
204+
memoryTreeWithDimensions.memoryTree.memoryUsage(),
205+
1,
192206
true,
193207
new JobId("foo"), Log.noOpLog()
194208
))

applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/GraphProjectMemoryUsageService.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ public class GraphProjectMemoryUsageService {
3939
private final Log log;
4040
private final GraphDatabaseService graphDatabaseService;
4141
private final MemoryTracker memoryTracker;
42+
private final String username;
4243

43-
public GraphProjectMemoryUsageService(Log log, GraphDatabaseService graphDatabaseService,
44+
public GraphProjectMemoryUsageService(String username,Log log, GraphDatabaseService graphDatabaseService,
4445
MemoryTracker memoryTracker
4546
) {
4647
this.log = log;
4748
this.graphDatabaseService = graphDatabaseService;
4849
this.memoryTracker = memoryTracker;
50+
this.username = username;
4951
}
5052

5153
public void validateMemoryUsage(
@@ -57,6 +59,7 @@ public void validateMemoryUsage(
5759
GraphProjectConfig configuration
5860
) {
5961
memoryUsageValidator().tryValidateMemoryUsage(
62+
"Loading",
6063
configuration,
6164
graphProjectConfig -> getEstimate(
6265
databaseId,
@@ -105,7 +108,7 @@ private MemoryUsageValidator memoryUsageValidator() {
105108
.resolveDependency(Config.class);
106109
var useMaxMemoryEstimation = neo4jConfig.get(GdsSettings.validateUsingMaxMemoryEstimation());
107110

108-
return new MemoryUsageValidator(memoryTracker, useMaxMemoryEstimation, log);
111+
return new MemoryUsageValidator(username,memoryTracker, useMaxMemoryEstimation, log);
109112
}
110113

111114
private GraphLoaderContext graphLoaderContext(

applications/graph-store-catalog/src/main/java/org/neo4j/gds/applications/graphstorecatalog/MemoryUsageValidator.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,17 @@ public class MemoryUsageValidator {
4040
private final Log log;
4141
private final boolean useMaxMemoryEstimation;
4242
private final MemoryTracker memoryTracker;
43+
private final String username;
4344

44-
public MemoryUsageValidator(MemoryTracker memoryTracker, boolean useMaxMemoryEstimation, Log log) {
45+
public MemoryUsageValidator(String username,MemoryTracker memoryTracker, boolean useMaxMemoryEstimation, Log log) {
4546
this.log = log;
4647
this.useMaxMemoryEstimation = useMaxMemoryEstimation;
4748
this.memoryTracker = memoryTracker;
49+
this.username = username;
4850
}
4951

5052
public <C extends BaseConfig & JobIdConfig> MemoryRange tryValidateMemoryUsage(
53+
String taskName,
5154
C config,
5255
Function<C, MemoryTreeWithDimensions> runEstimation
5356
) {
@@ -58,11 +61,14 @@ public <C extends BaseConfig & JobIdConfig> MemoryRange tryValidateMemoryUsage(
5861
if (config.sudo()) {
5962
log.debug("Sudo mode: Won't check for available memory.");
6063
memoryTracker.track(
64+
username,
65+
taskName,
6166
config.jobId(),
6267
useMaxMemoryEstimation ? estimatedMemoryRange.max : estimatedMemoryRange.min
6368
);
6469
} else {
6570
validateMemoryUsage(
71+
username,
6672
estimatedMemoryRange,
6773
memoryTracker.availableMemory(),
6874
useMaxMemoryEstimation,
@@ -78,6 +84,7 @@ public <C extends BaseConfig & JobIdConfig> MemoryRange tryValidateMemoryUsage(
7884
}
7985

8086
void validateMemoryUsage(
87+
String taskName,
8188
MemoryRange estimatedMemoryRange,
8289
long availableBytes,
8390
boolean useMaxMemoryEstimation,
@@ -86,6 +93,7 @@ void validateMemoryUsage(
8693
) {
8794
if (useMaxMemoryEstimation) {
8895
validateMemoryUsage(
96+
taskName,
8997
availableBytes,
9098
estimatedMemoryRange.max,
9199
"maximum",
@@ -97,6 +105,7 @@ void validateMemoryUsage(
97105
);
98106
} else {
99107
validateMemoryUsage(
108+
taskName,
100109
availableBytes,
101110
estimatedMemoryRange.min,
102111
"minimum",
@@ -106,6 +115,7 @@ void validateMemoryUsage(
106115
}
107116

108117
private void validateMemoryUsage(
118+
String taskName,
109119
long availableBytes,
110120
long requiredBytes,
111121
String memoryString,
@@ -137,6 +147,6 @@ private void validateMemoryUsage(
137147
log.info(message);
138148
throw new IllegalStateException(message);
139149
}
140-
memoryTracker.track(jobId, requiredBytes);
150+
memoryTracker.track(username,taskName,jobId, requiredBytes);
141151
}
142152
}

0 commit comments

Comments
 (0)