Skip to content

Commit a7a6c2e

Browse files
authored
Merge pull request #690 from zhenlineo/4.0-windows-server-start
Fixing windows server start error
2 parents 979f102 + 77475b5 commit a7a6c2e

File tree

6 files changed

+163
-81
lines changed

6 files changed

+163
-81
lines changed

driver/src/main/java/org/neo4j/driver/internal/util/ErrorUtil.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import io.netty.util.internal.PlatformDependent;
2222

23+
import java.util.Objects;
2324
import java.util.concurrent.ExecutionException;
2425
import java.util.stream.Stream;
2526

@@ -147,6 +148,22 @@ public static void addSuppressed( Throwable mainError, Throwable error )
147148
}
148149
}
149150

151+
public static Throwable getRootCause( Throwable error )
152+
{
153+
Objects.requireNonNull( error );
154+
Throwable cause = error.getCause();
155+
if ( cause == null )
156+
{
157+
// Nothing causes this error, returns the error itself
158+
return error;
159+
}
160+
while ( cause.getCause() != null )
161+
{
162+
cause = cause.getCause();
163+
}
164+
return cause;
165+
}
166+
150167
/**
151168
* Exception which is merely a holder of an async stacktrace, which is not the primary stacktrace users are interested in.
152169
* Used for blocking API calls that block on async API calls.

driver/src/test/java/org/neo4j/driver/integration/ConnectionPoolIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ void shouldRecoverFromDownedServer() throws Throwable
8888
sessionGrabber.start();
8989

9090
// When
91-
neo4j.restartDb();
91+
neo4j.forceRestartDb();
9292

9393
// Then we accept a hump with failing sessions, but demand that failures stop as soon as the server is back up.
9494
sessionGrabber.assertSessionsAvailableWithin( 60 );

driver/src/test/java/org/neo4j/driver/integration/async/AsyncSessionIT.java

Lines changed: 4 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,8 @@
5454
import org.neo4j.driver.internal.util.DisabledOnNeo4jWith;
5555
import org.neo4j.driver.internal.util.EnabledOnNeo4jWith;
5656
import org.neo4j.driver.internal.util.Futures;
57-
import org.neo4j.driver.summary.ResultSummary;
5857
import org.neo4j.driver.summary.QueryType;
58+
import org.neo4j.driver.summary.ResultSummary;
5959
import org.neo4j.driver.types.Node;
6060
import org.neo4j.driver.util.DatabaseExtension;
6161
import org.neo4j.driver.util.ParallelizableIT;
@@ -174,33 +174,6 @@ void shouldFailWhenQueryFailsAtRuntime()
174174
assertThat( e, is( arithmeticError() ) );
175175
}
176176

177-
@Test
178-
void shouldFailWhenServerIsRestarted()
179-
{
180-
int queryCount = 10_000;
181-
182-
String query = "UNWIND range(1, 100) AS x " +
183-
"CREATE (n1:Node {value: x})-[r:LINKED {value: x}]->(n2:Node {value: x}) " +
184-
"DETACH DELETE n1, n2 " +
185-
"RETURN x";
186-
187-
assertThrows( ServiceUnavailableException.class, () ->
188-
{
189-
for ( int i = 0; i < queryCount; i++ )
190-
{
191-
ResultCursor cursor = await( session.runAsync( query ) );
192-
193-
if ( i == 0 )
194-
{
195-
neo4j.stopDb();
196-
}
197-
198-
List<Record> records = await( cursor.listAsync() );
199-
assertEquals( 100, records.size() );
200-
}
201-
} );
202-
}
203-
204177
@Test
205178
void shouldAllowNestedQueries()
206179
{
@@ -580,24 +553,6 @@ void shouldConsumeNonEmptyCursor()
580553
testConsume( "UNWIND [42, 42] AS x RETURN x" );
581554
}
582555

583-
@Test
584-
void shouldRunAfterRunFailureToAcquireConnection()
585-
{
586-
neo4j.stopDb();
587-
588-
assertThrows( ServiceUnavailableException.class, () ->
589-
{
590-
ResultCursor cursor = await( session.runAsync( "RETURN 42" ) );
591-
await( cursor.nextAsync() );
592-
} );
593-
594-
neo4j.startDb();
595-
596-
ResultCursor cursor2 = await( session.runAsync( "RETURN 42" ) );
597-
Record record = await( cursor2.singleAsync() );
598-
assertEquals( 42, record.get( 0 ).asInt() );
599-
}
600-
601556
@Test
602557
@DisabledOnNeo4jWith( BOLT_V3 )
603558
void shouldRunAfterBeginTxFailureOnBookmark()
@@ -632,26 +587,6 @@ void shouldNotRunAfterBeginTxFailureOnBookmark()
632587
assertThrows( ClientException.class, () -> await( cursor.singleAsync() ) );
633588
}
634589

635-
@Test
636-
void shouldBeginTxAfterRunFailureToAcquireConnection()
637-
{
638-
neo4j.stopDb();
639-
640-
assertThrows( ServiceUnavailableException.class, () ->
641-
{
642-
ResultCursor cursor = await( session.runAsync( "RETURN 42" ) );
643-
await( cursor.consumeAsync() );
644-
} );
645-
646-
neo4j.startDb();
647-
648-
AsyncTransaction tx = await( session.beginTransactionAsync() );
649-
ResultCursor cursor2 = await( tx.runAsync( "RETURN 42" ) );
650-
Record record = await( cursor2.singleAsync() );
651-
assertEquals( 42, record.get( 0 ).asInt() );
652-
assertNull( await( tx.rollbackAsync() ) );
653-
}
654-
655590
@Test
656591
void shouldExecuteReadTransactionUntilSuccessWhenWorkThrows()
657592
{
@@ -886,7 +821,7 @@ private Future<List<CompletionStage<Record>>> runNestedQueries( ResultCursor inp
886821
}
887822

888823
private void runNestedQueries(ResultCursor inputCursor, List<CompletionStage<Record>> stages,
889-
CompletableFuture<List<CompletionStage<Record>>> resultFuture )
824+
CompletableFuture<List<CompletionStage<Record>>> resultFuture )
890825
{
891826
final CompletionStage<Record> recordResponse = inputCursor.nextAsync();
892827
stages.add( recordResponse );
@@ -909,7 +844,7 @@ else if ( record != null )
909844
}
910845

911846
private void runNestedQuery(ResultCursor inputCursor, Record record,
912-
List<CompletionStage<Record>> stages, CompletableFuture<List<CompletionStage<Record>>> resultFuture )
847+
List<CompletionStage<Record>> stages, CompletableFuture<List<CompletionStage<Record>>> resultFuture )
913848
{
914849
Node node = record.get( 0 ).asNode();
915850
long id = node.get( "id" ).asLong();
@@ -1031,7 +966,7 @@ public CompletionStage<Record> execute( AsyncTransaction tx )
1031966
}
1032967

1033968
private void processQueryResult(ResultCursor cursor, Throwable error,
1034-
CompletableFuture<Record> resultFuture )
969+
CompletableFuture<Record> resultFuture )
1035970
{
1036971
if ( error != null )
1037972
{
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (c) 2002-2020 "Neo4j,"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver.integration.async;
20+
21+
import org.junit.jupiter.api.AfterEach;
22+
import org.junit.jupiter.api.BeforeEach;
23+
import org.junit.jupiter.api.Test;
24+
import org.junit.jupiter.api.extension.RegisterExtension;
25+
26+
import java.util.List;
27+
28+
import org.neo4j.driver.Record;
29+
import org.neo4j.driver.async.AsyncSession;
30+
import org.neo4j.driver.async.AsyncTransaction;
31+
import org.neo4j.driver.async.ResultCursor;
32+
import org.neo4j.driver.exceptions.ServiceUnavailableException;
33+
import org.neo4j.driver.util.DatabaseExtension;
34+
import org.neo4j.driver.util.ParallelizableIT;
35+
36+
import static org.junit.jupiter.api.Assertions.assertEquals;
37+
import static org.junit.jupiter.api.Assertions.assertNull;
38+
import static org.junit.jupiter.api.Assertions.assertThrows;
39+
import static org.neo4j.driver.util.TestUtil.await;
40+
41+
@ParallelizableIT
42+
class AsyncSessionServerRestartIT
43+
{
44+
@RegisterExtension
45+
static final DatabaseExtension neo4j = new DatabaseExtension();
46+
47+
private AsyncSession session;
48+
49+
@BeforeEach
50+
void setUp()
51+
{
52+
session = neo4j.driver().asyncSession();
53+
}
54+
55+
@AfterEach
56+
void tearDown()
57+
{
58+
session.closeAsync();
59+
}
60+
61+
@Test
62+
void shouldFailWhenServerIsRestarted()
63+
{
64+
int queryCount = 10_000;
65+
66+
String query = "UNWIND range(1, 100) AS x " +
67+
"CREATE (n1:Node {value: x})-[r:LINKED {value: x}]->(n2:Node {value: x}) " +
68+
"DETACH DELETE n1, n2 " +
69+
"RETURN x";
70+
71+
assertThrows( ServiceUnavailableException.class, () ->
72+
{
73+
for ( int i = 0; i < queryCount; i++ )
74+
{
75+
ResultCursor cursor = await( session.runAsync( query ) );
76+
77+
if ( i == 0 )
78+
{
79+
neo4j.stopDb();
80+
}
81+
82+
List<Record> records = await( cursor.listAsync() );
83+
assertEquals( 100, records.size() );
84+
}
85+
} );
86+
neo4j.startDb();
87+
}
88+
89+
@Test
90+
void shouldRunAfterRunFailureToAcquireConnection()
91+
{
92+
neo4j.stopDb();
93+
94+
assertThrows( ServiceUnavailableException.class, () ->
95+
{
96+
ResultCursor cursor = await( session.runAsync( "RETURN 42" ) );
97+
await( cursor.nextAsync() );
98+
} );
99+
100+
neo4j.startDb();
101+
102+
ResultCursor cursor2 = await( session.runAsync( "RETURN 42" ) );
103+
Record record = await( cursor2.singleAsync() );
104+
assertEquals( 42, record.get( 0 ).asInt() );
105+
}
106+
107+
@Test
108+
void shouldBeginTxAfterRunFailureToAcquireConnection()
109+
{
110+
neo4j.stopDb();
111+
112+
assertThrows( ServiceUnavailableException.class, () ->
113+
{
114+
ResultCursor cursor = await( session.runAsync( "RETURN 42" ) );
115+
await( cursor.consumeAsync() );
116+
} );
117+
118+
neo4j.startDb();
119+
120+
AsyncTransaction tx = await( session.beginTransactionAsync() );
121+
ResultCursor cursor2 = await( tx.runAsync( "RETURN 42" ) );
122+
Record record = await( cursor2.singleAsync() );
123+
assertEquals( 42, record.get( 0 ).asInt() );
124+
assertNull( await( tx.rollbackAsync() ) );
125+
}
126+
}

driver/src/test/java/org/neo4j/driver/util/DatabaseExtension.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,6 @@ public TypeSystem typeSystem()
7676
return driver().defaultTypeSystem();
7777
}
7878

79-
public void restartDb()
80-
{
81-
runner.restartNeo4j();
82-
}
83-
8479
public void forceRestartDb()
8580
{
8681
runner.forceToRestart();

driver/src/test/java/org/neo4j/driver/util/Neo4jRunner.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.neo4j.driver.Driver;
3535
import org.neo4j.driver.GraphDatabase;
3636
import org.neo4j.driver.internal.BoltServerAddress;
37+
import org.neo4j.driver.internal.util.ErrorUtil;
3738

3839
import static java.util.Arrays.asList;
3940
import static java.util.logging.Level.INFO;
@@ -116,7 +117,16 @@ private Neo4jRunner() throws IOException
116117
{
117118
installNeo4j();
118119
updateServerSettingsFile();
119-
startNeo4j();
120+
try
121+
{
122+
startNeo4j();
123+
}
124+
catch ( Exception e )
125+
{
126+
debug( "Failed to start server first time due to error: " + ErrorUtil.getRootCause( e ).getMessage() );
127+
debug( "Retry to start server again." );
128+
startNeo4j();
129+
}
120130
}
121131
finally
122132
{
@@ -186,7 +196,7 @@ private void installNeo4j() throws IOException
186196
public void startNeo4j()
187197
{
188198
debug( "Starting server..." );
189-
executeCommand( "neoctrl-start", HOME_DIR );
199+
executeCommand( "neoctrl-start", HOME_DIR, "-v" );
190200
debug( "Server started." );
191201
}
192202

@@ -286,16 +296,15 @@ private ServerStatus serverStatus()
286296
}
287297
}
288298

289-
private boolean updateServerSettings( Neo4jSettings settingsUpdate )
299+
private boolean updateServerSettings( Neo4jSettings newSetting )
290300
{
291-
Neo4jSettings updatedSettings = currentSettings.updateWith( settingsUpdate );
292-
if ( currentSettings.equals( updatedSettings ) )
301+
if ( currentSettings.equals( newSetting ) )
293302
{
294303
return false;
295304
}
296305
else
297306
{
298-
currentSettings = updatedSettings;
307+
currentSettings = newSetting;
299308
}
300309
updateServerSettingsFile();
301310
return true;

0 commit comments

Comments
 (0)