Skip to content

Commit

Permalink
v2.18.1 (#2261)
Browse files Browse the repository at this point in the history
  • Loading branch information
skamril authored Dec 2, 2024
2 parents e3e752b + b66a816 commit 3cbd45a
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 43 deletions.
4 changes: 2 additions & 2 deletions antarest/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

# Standard project metadata

__version__ = "2.18.0"
__version__ = "2.18.1"
__author__ = "RTE, Antares Web Team"
__date__ = "2024-11-29"
__date__ = "2024-12-02"
# noinspection SpellCheckingInspection
__credits__ = "(c) Réseau de Transport de l’Électricité (RTE)"

Expand Down
20 changes: 15 additions & 5 deletions antarest/eventbus/business/redis_eventbus.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

logger = logging.getLogger(__name__)
REDIS_STORE_KEY = "events"
MAX_EVENTS_LIST_SIZE = 1000


class RedisEventBus(IEventBusBackend):
Expand All @@ -41,14 +42,23 @@ def pull_queue(self, queue: str) -> Optional[Event]:
return None

def get_events(self) -> List[Event]:
messages = []
try:
event = self.pubsub.get_message(ignore_subscribe_messages=True)
if event is not None:
return [Event.parse_raw(event["data"])]
while msg := self.pubsub.get_message(ignore_subscribe_messages=True):
messages.append(msg)
if len(messages) >= MAX_EVENTS_LIST_SIZE:
break
except Exception:
logger.error("Failed to retrieve or parse event !", exc_info=True)
logger.error("Failed to retrieve events !", exc_info=True)

return []
events = []
for msg in messages:
try:
events.append(Event.model_validate_json(msg["data"]))
except Exception:
logger.error(f"Failed to parse event ! {msg}", exc_info=True)

return events

def clear_events(self) -> None:
# Nothing to do
Expand Down
18 changes: 14 additions & 4 deletions antarest/eventbus/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@
logger = logging.getLogger(__name__)


EVENT_LOOP_REST_TIME = 0.2


class EventBusService(IEventBus):
def __init__(self, backend: IEventBusBackend, autostart: bool = True) -> None:
self.backend = backend
Expand Down Expand Up @@ -76,18 +79,22 @@ def remove_listener(self, listener_id: str) -> None:

async def _run_loop(self) -> None:
while True:
time.sleep(0.2)
try:
await self._on_events()
processed_events_count = await self._on_events()
# Give the loop some rest if it has nothing to do
if processed_events_count == 0:
await asyncio.sleep(EVENT_LOOP_REST_TIME)
except Exception as e:
logger.error("Unexpected error when processing events", exc_info=e)

async def _on_events(self) -> None:
async def _on_events(self) -> int:
processed_events_count = 0
with self.lock:
for queue in self.consumers:
if len(self.consumers[queue]) > 0:
event = self.backend.pull_queue(queue)
while event is not None:
processed_events_count += 1
try:
await list(self.consumers[queue].values())[
random.randint(0, len(self.consumers[queue]) - 1)
Expand All @@ -99,7 +106,9 @@ async def _on_events(self) -> None:
)
event = self.backend.pull_queue(queue)

for e in self.backend.get_events():
events = self.backend.get_events()
processed_events_count += len(events)
for e in events:
if e.type in self.listeners:
responses = await asyncio.gather(
*[
Expand All @@ -115,6 +124,7 @@ async def _on_events(self) -> None:
exc_info=res,
)
self.backend.clear_events()
return processed_events_count

def _async_loop(self, new_loop: bool = True) -> None:
loop = asyncio.new_event_loop() if new_loop else asyncio.get_event_loop()
Expand Down
16 changes: 15 additions & 1 deletion docs/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,22 @@
Antares Web Changelog
=====================

v2.18.1 (2024-12-02)
--------------------

## What's Changed

### Bug Fixes

* **ui-tablemode**: style missing [`2257`](https://github.com/AntaresSimulatorTeam/AntaREST/pull/2257)
* **ui-studies**: multiple API calls on study list view [`2258`](https://github.com/AntaresSimulatorTeam/AntaREST/pull/2258)
* **events**: avoid slow processing of events [`2259`](https://github.com/AntaresSimulatorTeam/AntaREST/pull/2259)

**Full Changelog**: https://github.com/AntaresSimulatorTeam/AntaREST/compare/v2.18.0...v2.18.1


v2.18.0 (2024-11-29)
-------------------
--------------------

## What's Changed

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ requires = ["setuptools"]

[project]
name = "AntaREST"
version = "2.18.0"
version = "2.18.1"
authors = [{name="RTE, Antares Web Team", email="[email protected]" }]
description="Antares Server"
readme = {file = "README.md", content-type = "text/markdown"}
Expand Down
6 changes: 6 additions & 0 deletions resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,9 @@ logging:

# True to get sqlalchemy logs
debug: False

# Uncomment these lines to use redis as a backend for the eventbus
# It is required to use redis when using this application on multiple workers in a preforked model like gunicorn for instance
#redis:
# host: localhost
# port: 6379
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ sonar.exclusions=antarest/gui.py,antarest/main.py
sonar.python.coverage.reportPaths=coverage.xml
sonar.python.version=3.11
sonar.javascript.lcov.reportPaths=webapp/coverage/lcov.info
sonar.projectVersion=2.18.0
sonar.projectVersion=2.18.1
sonar.coverage.exclusions=antarest/gui.py,antarest/main.py,antarest/singleton_services.py,antarest/worker/archive_worker_service.py,webapp/**/*,,antarest/fastapi_jwt_auth/**
5 changes: 3 additions & 2 deletions tests/eventbus/test_redis_event_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ def test_lifecycle():
payload="foo",
permissions=PermissionInfo(public_mode=PublicMode.READ),
)

serialized = event.model_dump_json()
pubsub_mock.get_message.return_value = {"data": serialized}
pubsub_mock.get_message = Mock(side_effect=[{"data": serialized}, {"data": serialized}, None])
eventbus.push_event(event)
redis_client.publish.assert_called_once_with("events", serialized)
assert eventbus.get_events() == [event]
assert eventbus.get_events() == [event, event]
4 changes: 2 additions & 2 deletions webapp/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion webapp/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "antares-web",
"version": "2.18.0",
"version": "2.18.1",
"private": true,
"type": "module",
"scripts": {
Expand Down
45 changes: 21 additions & 24 deletions webapp/src/components/App/Studies/StudyCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -405,30 +405,27 @@ const StudyCard = memo((props: Props) => {
setOpenDialog={setOpenDialog}
/>
</CardActions>
<PropertiesDialog
open={openDialog === "properties"}
onClose={closeDialog}
study={study}
/>
<ConfirmationDialog
title={t("dialog.title.confirmation")}
onCancel={closeDialog}
onConfirm={handleDelete}
alert="warning"
open={openDialog === "delete"}
>
{t("studies.question.delete")}
</ConfirmationDialog>
<ExportModal
open={openDialog === "export"}
onClose={closeDialog}
study={study}
/>
<MoveStudyDialog
open={openDialog === "move"}
onClose={closeDialog}
study={study}
/>
{/* Keep conditional rendering for dialogs and not use only `open` property, because API calls are made on mount */}
{openDialog === "properties" && (
<PropertiesDialog open onClose={closeDialog} study={study} />
)}
{openDialog === "delete" && (
<ConfirmationDialog
open
title={t("dialog.title.confirmation")}
onCancel={closeDialog}
onConfirm={handleDelete}
alert="warning"
>
{t("studies.question.delete")}
</ConfirmationDialog>
)}
{openDialog === "export" && (
<ExportModal open onClose={closeDialog} study={study} />
)}
{openDialog === "move" && (
<MoveStudyDialog open onClose={closeDialog} study={study} />
)}
</Card>
);
}, areEqual);
Expand Down
1 change: 1 addition & 0 deletions webapp/src/components/common/Handsontable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { styled } from "@mui/material";
import { forwardRef } from "react";
import * as RA from "ramda-adjunct";
import { SECONDARY_MAIN_COLOR } from "../../theme";
import "handsontable/dist/handsontable.min.css";

// Register Handsontable's modules
registerAllModules();
Expand Down

0 comments on commit 3cbd45a

Please sign in to comment.