Skip to content

Commit 6f56a3b

Browse files
ivandaschisapego
authored andcommitted
IGNITE-14245 Fix infinite loop while trying to get affinity mapping on failed node
This closes #20
1 parent b2030be commit 6f56a3b

4 files changed

Lines changed: 98 additions & 25 deletions

File tree

.travis.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one or more
2+
# contributor license agreements. See the NOTICE file distributed with
3+
# this work for additional information regarding copyright ownership.
4+
# The ASF licenses this file to You under the Apache License, Version 2.0
5+
# (the "License"); you may not use this file except in compliance with
6+
# the License. You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
language: python
17+
sudo: required
18+
19+
addons:
20+
apt:
21+
packages:
22+
- openjdk-8-jdk
23+
24+
env:
25+
global:
26+
- IGNITE_VERSION=2.9.1
27+
- IGNITE_HOME=/opt/ignite
28+
29+
before_install:
30+
- curl -L https://apache-mirror.rbc.ru/pub/apache/ignite/${IGNITE_VERSION}/apache-ignite-slim-${IGNITE_VERSION}-bin.zip > ignite.zip
31+
- unzip ignite.zip -d /opt
32+
- mv /opt/apache-ignite-slim-${IGNITE_VERSION}-bin /opt/ignite
33+
- mv /opt/ignite/libs/optional/ignite-log4j2 /opt/ignite/libs/
34+
35+
jobs:
36+
include:
37+
- python: '3.6'
38+
arch: amd64
39+
env: TOXENV=py36
40+
- python: '3.7'
41+
arch: amd64
42+
env: TOXENV=py37
43+
- python: '3.8'
44+
arch: amd64
45+
env: TOXENV=py38
46+
- python: '3.9'
47+
arch: amd64
48+
env: TOXENV=py39
49+
50+
install: pip install tox
51+
script: tox

pyignite/cache.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ def get_best_node(
264264
break
265265
except connection_errors:
266266
# retry if connection failed
267+
conn = self._client.random_node
267268
pass
268269
except CacheError:
269270
# server did not create mapping in time

tests/affinity/conftest.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
from pyignite.api import cache_create, cache_destroy
2020
from tests.util import start_ignite_gen
2121

22+
# Sometimes on slow testing servers and unstable topology
23+
# default timeout is not enough for cache ops.
24+
CLIENT_SOCKET_TIMEOUT = 20.0
25+
2226

2327
@pytest.fixture(scope='module', autouse=True)
2428
def server1():
@@ -37,7 +41,7 @@ def server3():
3741

3842
@pytest.fixture
3943
def client():
40-
client = Client(partition_aware=True)
44+
client = Client(partition_aware=True, timeout=CLIENT_SOCKET_TIMEOUT)
4145

4246
client.connect([('127.0.0.1', 10800 + i) for i in range(1, 4)])
4347

@@ -48,7 +52,7 @@ def client():
4852

4953
@pytest.fixture
5054
def client_not_connected():
51-
client = Client(partition_aware=True)
55+
client = Client(partition_aware=True, timeout=CLIENT_SOCKET_TIMEOUT)
5256
yield client
5357
client.close()
5458

tests/affinity/test_affinity_bad_servers.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,62 @@
1616
import pytest
1717

1818
from pyignite.exceptions import ReconnectError
19-
from tests.util import start_ignite, kill_process_tree
19+
from tests.affinity.conftest import CLIENT_SOCKET_TIMEOUT
20+
from tests.util import start_ignite, kill_process_tree, get_client
2021

2122

22-
def test_client_with_multiple_bad_servers(client_not_connected):
23+
@pytest.fixture(params=['with-partition-awareness', 'without-partition-awareness'])
24+
def with_partition_awareness(request):
25+
yield request.param == 'with-partition-awareness'
26+
27+
28+
def test_client_with_multiple_bad_servers(with_partition_awareness):
2329
with pytest.raises(ReconnectError) as e_info:
24-
client_not_connected.connect([("127.0.0.1", 10900), ("127.0.0.1", 10901)])
30+
with get_client(partition_aware=with_partition_awareness) as client:
31+
client.connect([("127.0.0.1", 10900), ("127.0.0.1", 10901)])
2532
assert str(e_info.value) == "Can not connect."
2633

2734

28-
def test_client_with_failed_server(request, client_not_connected):
35+
def test_client_with_failed_server(request, with_partition_awareness):
2936
srv = start_ignite(idx=4)
3037
try:
31-
client_not_connected.connect([("127.0.0.1", 10804)])
32-
cache = client_not_connected.get_or_create_cache(request.node.name)
33-
cache.put(1, 1)
34-
kill_process_tree(srv.pid)
35-
with pytest.raises(ConnectionResetError):
36-
cache.get(1)
38+
with get_client(partition_aware=with_partition_awareness) as client:
39+
client.connect([("127.0.0.1", 10804)])
40+
cache = client.get_or_create_cache(request.node.name)
41+
cache.put(1, 1)
42+
kill_process_tree(srv.pid)
43+
44+
if with_partition_awareness:
45+
ex_class = (ReconnectError, ConnectionResetError)
46+
else:
47+
ex_class = ConnectionResetError
48+
49+
with pytest.raises(ex_class):
50+
cache.get(1)
3751
finally:
3852
kill_process_tree(srv.pid)
3953

4054

41-
def test_client_with_recovered_server(request, client_not_connected):
55+
def test_client_with_recovered_server(request, with_partition_awareness):
4256
srv = start_ignite(idx=4)
4357
try:
44-
client_not_connected.connect([("127.0.0.1", 10804)])
45-
cache = client_not_connected.get_or_create_cache(request.node.name)
46-
cache.put(1, 1)
58+
with get_client(partition_aware=with_partition_awareness, timeout=CLIENT_SOCKET_TIMEOUT) as client:
59+
client.connect([("127.0.0.1", 10804)])
60+
cache = client.get_or_create_cache(request.node.name)
61+
cache.put(1, 1)
4762

48-
# Kill and restart server
49-
kill_process_tree(srv.pid)
50-
srv = start_ignite(idx=4)
63+
# Kill and restart server
64+
kill_process_tree(srv.pid)
65+
srv = start_ignite(idx=4)
5166

52-
# First request fails
53-
with pytest.raises(Exception):
54-
cache.put(1, 2)
67+
# First request may fail.
68+
try:
69+
cache.put(1, 2)
70+
except:
71+
pass
5572

56-
# Retry succeeds
57-
cache.put(1, 2)
58-
assert cache.get(1) == 2
73+
# Retry succeeds
74+
cache.put(1, 2)
75+
assert cache.get(1) == 2
5976
finally:
6077
kill_process_tree(srv.pid)

0 commit comments

Comments
 (0)