Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,15 @@ get_mutations_in_progress_count("SOME_DATABASE", "SOME_TABLE_IN_DATABASE")
# 5
```

#### notalib.django.clickhouse.mutations.is_mutations_running

True or False, depending on the presence of unfulfilled mutations.

```python
is_mutations_running("SOME_DATABASE", "SOME_TABLE_IN_DATABASE")
True
```

#### notalib.django.clickhouse.wait.wait_result :fire:

Waits until all mutations for the given table are complete.
Expand Down
38 changes: 28 additions & 10 deletions notalib/django/clickhouse/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,11 @@ def get_mutations_in_progress_count(db_name: str, table_name: str) -> int:
"""
Requests from the System.Mutants table the number of mutations in progress.

Parameters
----------
db_name: str
Must contain name of existed database with tables.
table_name: str
Must contain name of existed table in database with db_name.

Returns
-------
int
Args:
db_name: Must contain name of existed database with tables.
table_name: Must contain name of existed table in database with db_name.

Returns:
Number of mutants in progress.
"""

Expand All @@ -39,3 +34,26 @@ def get_mutations_in_progress_count(db_name: str, table_name: str) -> int:
query.params = {'db_name': db_name, 'table_name': table_name}

return query.execute_val()


def is_mutations_running(db_name: str, table_name: str) -> bool:
"""
Checks for the presence of running mutations.

Args:
db_name: Name of database to check.
table_name: Name of table to check.

Returns:
Returns True if there are running mutations, otherwise False.
"""
query = Query()
query.q = text("""\
SELECT 1
FROM system.mutations
WHERE database = :db_name AND table = :table_name AND is_done = 0
LIMIT 1
""")
query.params = {"db_name": db_name, "table_name": table_name}

return bool(query.execute_list())
46 changes: 33 additions & 13 deletions notalib/django/clickhouse/mutations_test.py
Original file line number Diff line number Diff line change
@@ -1,30 +1,50 @@
from notalib.django.clickhouse.mutations import get_mutations_in_progress_count
from notalib.django.clickhouse.mutations import get_mutations_in_progress_count, is_mutations_running
from notalib.django.clickhouse.base import Query

from unittest.mock import patch
from unittest.mock import patch, Mock


class FakeQuery(Query):
instance = None
def make_fake_query():
class FakeQuery(Query):
instance = None

def __new__(cls, *args, **kwargs) -> "FakeQuery":
if cls.instance is None:
cls.instance = super().__new__(cls, *args, **kwargs)
def __new__(cls, *args, **kwargs) -> "FakeQuery":
if cls.instance is None:
cls.instance = super().__new__(cls, *args, **kwargs)

return cls.instance
return cls.instance

def __init__(self, q=None, **kwargs):
if not self is self.__class__.instance:
super().__init__(q, **kwargs)
def __init__(self, q=None, **kwargs):
if not self is self.__class__.instance:
super().__init__(q, **kwargs)

def execute_val(self) -> None:
return None
def execute_val(self) -> None:
return None

def execute_list(self) -> None:
return None


return FakeQuery


def test_get_mutations_in_progress_count():
FakeQuery = make_fake_query()

with patch("notalib.django.clickhouse.mutations.Query", new=FakeQuery):
database, table = "TEST_DATABASE", "TEST_TABLE"
get_mutations_in_progress_count(database, table)
query = FakeQuery()

assert query.params == {'db_name': database, 'table_name': table}


def test_is_mutations_running():
FakeQuery = make_fake_query()

with patch("notalib.django.clickhouse.mutations.Query", new=FakeQuery):
database, table = "TEST_DATABASE", "TEST_TABLE"
is_mutations_running(database, table)
query = FakeQuery()

assert query.params == {"db_name": database, "table_name": table}
24 changes: 9 additions & 15 deletions notalib/django/clickhouse/wait.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .mutations import get_mutations_in_progress_count
from .mutations import is_mutations_running

from time import sleep
from typing import Union
Expand All @@ -8,20 +8,14 @@ def wait_result(db_name: str, table_name: str, delay: Union[int, float] = 0.25)
"""
Suspends the program while there are incomplete mutant processes.

Parameters
----------
db_name: str
Database name in which the deletion operation was performed.
table_name: str
Table name in the {db_name} database in which the deletion operation was performed.
delay: Union[int, float]
Delay between system table polls.
Args:
db_name: Database name in which the deletion operation was performed.
table_name: Table name in the {db_name} database in which the deletion operation was performed.
delay: Delay between system table polls.

Notes
-----
Imagine that you are driving in a car to a railway crossing. A train is going to cross you by rail.
This function is a handbrake that will save you from crashing.
Notes:
Imagine that you are driving in a car to a railway crossing. A train is going to cross you by rail.
This function is a handbrake that will save you from crashing.
"""

while get_mutations_in_progress_count(db_name, table_name):
while is_mutations_running(db_name, table_name):
sleep(delay)
8 changes: 4 additions & 4 deletions notalib/django/clickhouse/wait_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@


def test_wait_result():
get_mutations_count_fn = SequenceFakeFunction([5, 0])
is_mutations_running_fn = SequenceFakeFunction([True, False])
sleep_fn = FakeFunction()

with patch("notalib.django.clickhouse.wait.get_mutations_in_progress_count", new=get_mutations_count_fn):
with patch("notalib.django.clickhouse.wait.is_mutations_running", new=is_mutations_running_fn):
with patch("notalib.django.clickhouse.wait.sleep", new=sleep_fn):
database, table, delay = "TEST_DATABASE", "TEST_TABLE", 5

wait_result(database, table, delay)
assert get_mutations_count_fn.last_call_args == (database, table)
assert get_mutations_count_fn.call_count == 2
assert is_mutations_running_fn.last_call_args == (database, table)
assert is_mutations_running_fn.call_count == 2

assert sleep_fn.last_call_args == (delay, )
assert sleep_fn.call_count == 1
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "notalib"
version = "2.4.0"
version = "2.5.0-rc0"
description = "A collection of utility functions & classes"
authors = ["m1kc (Max Musatov) <m1kc@yandex.ru>"]
license = "MIT"
Expand Down