Skip to content

Commit d8ea7cc

Browse files
authoredAug 7, 2024··
Integrate latest 3.12.1 changes (#347)
* Bumping example to the latest version * Adding option `skipFastLockRound` for transactions * Introducing HTTP DELETE `/_admin/log/level` to reset all log * Removing types-pkg-resources * Setting skip_fast_lock_round to None by default * Adding test coverage for `server_id` parameter
1 parent 324eb66 commit d8ea7cc

7 files changed

+86
-8
lines changed
 

‎arango/database.py

+39
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
ServerLicenseGetError,
5353
ServerLicenseSetError,
5454
ServerLogLevelError,
55+
ServerLogLevelResetError,
5556
ServerLogLevelSetError,
5657
ServerLogSettingError,
5758
ServerLogSettingSetError,
@@ -1003,6 +1004,35 @@ def response_handler(resp: Response) -> Json:
10031004

10041005
return self._execute(request, response_handler)
10051006

1007+
def reset_log_levels(self, server_id: Optional[str] = None) -> Result[Json]:
1008+
"""Reset the logging levels.
1009+
1010+
Revert the server’s log level settings to the values they had at startup,
1011+
as determined by the startup options specified on the command-line,
1012+
a configuration file, and the factory defaults.
1013+
1014+
:param server_id: Forward log level to a specific server. This makes it
1015+
easier to adjust the log levels in clusters because DB-Servers require
1016+
JWT authentication whereas Coordinators also support authentication
1017+
using usernames and passwords.
1018+
:type server_id: str | None
1019+
:return: New logging levels.
1020+
:rtype: dict
1021+
"""
1022+
params: Params = {}
1023+
if server_id is not None:
1024+
params["serverId"] = server_id
1025+
1026+
request = Request(method="delete", endpoint="/_admin/log/level", params=params)
1027+
1028+
def response_handler(resp: Response) -> Json:
1029+
if not resp.is_success:
1030+
raise ServerLogLevelResetError(resp, request)
1031+
result: Json = resp.body
1032+
return result
1033+
1034+
return self._execute(request, response_handler)
1035+
10061036
def reload_routing(self) -> Result[bool]:
10071037
"""Reload the routing information.
10081038
@@ -3020,6 +3050,7 @@ def begin_transaction(
30203050
allow_implicit: Optional[bool] = None,
30213051
lock_timeout: Optional[int] = None,
30223052
max_size: Optional[int] = None,
3053+
skip_fast_lock_round: Optional[bool] = None,
30233054
) -> "TransactionDatabase":
30243055
"""Begin a transaction.
30253056
@@ -3043,6 +3074,9 @@ def begin_transaction(
30433074
:type lock_timeout: int | None
30443075
:param max_size: Max transaction size in bytes.
30453076
:type max_size: int | None
3077+
:param skip_fast_lock_round: Whether to disable fast locking for write
3078+
operations.
3079+
:type skip_fast_lock_round: bool | None
30463080
:return: Database API wrapper object specifically for transactions.
30473081
:rtype: arango.database.TransactionDatabase
30483082
"""
@@ -3055,6 +3089,7 @@ def begin_transaction(
30553089
allow_implicit=allow_implicit,
30563090
lock_timeout=lock_timeout,
30573091
max_size=max_size,
3092+
skip_fast_lock_round=skip_fast_lock_round,
30583093
)
30593094

30603095
def begin_controlled_execution(
@@ -3191,6 +3226,8 @@ class TransactionDatabase(Database):
31913226
:param transaction_id: Initialize using an existing transaction instead of creating
31923227
a new transaction.
31933228
:type transaction_id: str | None
3229+
:param skip_fast_lock_round: Whether to disable fast locking for write operations.
3230+
:type skip_fast_lock_round: bool | None
31943231
"""
31953232

31963233
def __init__(
@@ -3204,6 +3241,7 @@ def __init__(
32043241
lock_timeout: Optional[int] = None,
32053242
max_size: Optional[int] = None,
32063243
transaction_id: Optional[str] = None,
3244+
skip_fast_lock_round: Optional[bool] = None,
32073245
) -> None:
32083246
self._executor: TransactionApiExecutor
32093247
super().__init__(
@@ -3218,6 +3256,7 @@ def __init__(
32183256
lock_timeout=lock_timeout,
32193257
max_size=max_size,
32203258
transaction_id=transaction_id,
3259+
skip_fast_lock_round=skip_fast_lock_round,
32213260
),
32223261
)
32233262

‎arango/exceptions.py

+4
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,10 @@ class ServerLogLevelError(ArangoServerError):
674674
"""Failed to retrieve server log levels."""
675675

676676

677+
class ServerLogLevelResetError(ArangoServerError):
678+
"""Failed to reset server log levels."""
679+
680+
677681
class ServerLogSettingError(ArangoServerError):
678682
"""Failed to retrieve server log settings."""
679683

‎arango/executor.py

+5
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,8 @@ class TransactionApiExecutor:
245245
:param transaction_id: Initialize using an existing transaction instead of starting
246246
a new transaction.
247247
:type transaction_id: str | None
248+
:param skip_fast_lock_round: Whether to disable fast locking for write operations.
249+
:type skip_fast_lock_round: bool | None
248250
"""
249251

250252
def __init__(
@@ -259,6 +261,7 @@ def __init__(
259261
max_size: Optional[int] = None,
260262
allow_dirty_read: bool = False,
261263
transaction_id: Optional[str] = None,
264+
skip_fast_lock_round: Optional[bool] = None,
262265
) -> None:
263266
self._conn = connection
264267

@@ -279,6 +282,8 @@ def __init__(
279282
data["lockTimeout"] = lock_timeout
280283
if max_size is not None:
281284
data["maxTransactionSize"] = max_size
285+
if skip_fast_lock_round is not None:
286+
data["skipFastLockRound"] = skip_fast_lock_round
282287

283288
if transaction_id is None:
284289
request = Request(

‎pyproject.toml

-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@ dev = [
5757
"pytest-cov>=3.0.0",
5858
"sphinx",
5959
"sphinx_rtd_theme",
60-
"types-pkg_resources",
6160
"types-requests",
6261
"types-setuptools",
6362
]

‎starter.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
# Usage:
77
# ./starter.sh [single|cluster] [community|enterprise] [version]
88
# Example:
9-
# ./starter.sh cluster enterprise 3.11.4
9+
# ./starter.sh cluster enterprise 3.12.1
1010

1111
setup="${1:-single}"
1212
license="${2:-community}"

‎tests/test_database.py

+15-2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
ServerEngineError,
2525
ServerLicenseSetError,
2626
ServerLogLevelError,
27+
ServerLogLevelResetError,
2728
ServerLogLevelSetError,
2829
ServerMetricsError,
2930
ServerModeSetError,
@@ -65,7 +66,7 @@ def test_database_attributes(db, username):
6566
assert isinstance(db.wal, WAL)
6667

6768

68-
def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret):
69+
def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret, db_version):
6970
# Test get properties
7071
properties = db.properties()
7172
assert "id" in properties
@@ -249,7 +250,8 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret):
249250
assert err.value.error_code in {11, 1228}
250251

251252
# Test get log levels
252-
assert isinstance(sys_db.log_levels(), dict)
253+
default_log_levels = sys_db.log_levels()
254+
assert isinstance(default_log_levels, dict)
253255

254256
# Test get log levels with bad database
255257
with assert_raises(ServerLogLevelError) as err:
@@ -296,6 +298,17 @@ def test_database_misc_methods(client, sys_db, db, bad_db, cluster, secret):
296298
assert "username" not in result_1
297299
assert result_1 == result_2
298300

301+
# Reset Log Settings
302+
if db.version() >= "3.12.1":
303+
if cluster:
304+
server_id = sys_db.cluster.server_id()
305+
assert isinstance(sys_db.reset_log_levels(server_id), dict)
306+
307+
result = sys_db.reset_log_levels()
308+
assert result == default_log_levels
309+
with assert_raises(ServerLogLevelResetError):
310+
bad_db.reset_log_levels()
311+
299312
# Test get storage engine
300313
engine = db.engine()
301314
assert engine["name"] in ["rocksdb"]

‎tests/test_transaction.py

+22-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from packaging import version
23

34
from arango.database import TransactionDatabase
45
from arango.exceptions import (
@@ -16,14 +17,15 @@ def test_transaction_execute_raw(db, col, docs):
1617
# Test execute raw transaction
1718
doc = docs[0]
1819
key = doc["_key"]
19-
result = db.execute_transaction(
20-
command=f"""
20+
command = f"""
2121
function (params) {{
2222
var db = require('internal').db;
2323
db.{col.name}.save({{'_key': params.key, 'val': 1}});
2424
return true;
2525
}}
26-
""",
26+
""" # noqa: E702 E231 E272 E202
27+
result = db.execute_transaction(
28+
command=command,
2729
params={"key": key},
2830
write=[col.name],
2931
read=[col.name],
@@ -43,7 +45,7 @@ def test_transaction_execute_raw(db, col, docs):
4345
assert err.value.error_code == 10
4446

4547

46-
def test_transaction_init(db, bad_db, col, username):
48+
def test_transaction_init(db, db_version, bad_db, col, username):
4749
txn_db = db.begin_transaction()
4850

4951
assert isinstance(txn_db, TransactionDatabase)
@@ -68,6 +70,22 @@ def test_transaction_init(db, bad_db, col, username):
6870
bad_db.begin_transaction()
6971
assert err.value.error_code in {11, 1228}
7072

73+
# Test all options
74+
kwargs = dict(
75+
read=col.name,
76+
write=col.name,
77+
exclusive=[],
78+
sync=True,
79+
allow_implicit=False,
80+
lock_timeout=1000,
81+
max_size=1024 * 1024,
82+
)
83+
if db_version >= version.parse("3.12.1"):
84+
kwargs["skip_fast_lock_round"] = True
85+
txn_db = db.begin_transaction(**kwargs)
86+
assert isinstance(txn_db, TransactionDatabase)
87+
assert txn_db.transaction_id is not None
88+
7189

7290
def test_transaction_status(db, col, docs):
7391
txn_db = db.begin_transaction(read=col.name)

0 commit comments

Comments
 (0)