Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add new backends_status #4333

Merged
merged 1 commit into from
Dec 18, 2024
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
3 changes: 2 additions & 1 deletion docker/run_jormungandr.sh
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ fi
if [ $monitor_processes -eq 1 ]
then
echo "!!!!!!!!!!!!!!!!!!!!! Start Jormungandr with monitoring service !!!!!!!!!!!!!!!!!!!!!"
uwsgi --cache2 $jormungandr_cache2 $max_requests --http :9090 --stats :5050 --lazy-apps --file $file & uwsgi --cache2 $monitor_cache2 --http :9091 --lazy-apps --file $file --processes 1 --listen 5
# JORMUNGANDR_IS_PUBLIC is set to True only for the use of /v1/backends_status
uwsgi --cache2 $jormungandr_cache2 $max_requests --http :9090 --stats :5050 --lazy-apps --file $file & JORMUNGANDR_IS_PUBLIC=True uwsgi --cache2 $monitor_cache2 --http :9091 --lazy-apps --file $file --processes 1 --listen 5
else
echo "!!!!!!!!!!!!!!!!!!!!! Start Jormungandr without monitoring service !!!!!!!!!!!!!!!!!!!!!"
uwsgi --cache2 $jormungandr_cache2 $max_requests --http :9090 --stats :5050 --lazy-apps --file $file
Expand Down
2 changes: 2 additions & 0 deletions source/jormungandr/jormungandr/default_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,5 @@

USE_EXCLUDED_ZONES = boolean(os.getenv('JORMUNGANDR_USE_EXCLUDED_ZONES', False))
ASGARD_S3_BUCKET = os.getenv('JORMUNGANDR_ASGARD_S3_BUCKET', '')

BACKENDS_STATUS_GREENLET_POOL_SIZE = os.getenv('JORMUNGANDR_BACKENDS_STATUS_GREENLET_POOL_SIZE', 10)
3 changes: 3 additions & 0 deletions source/jormungandr/jormungandr/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,9 @@ def get_pt_planner(self, pt_planner_id=None):
pt_planner_id = pt_planner_id or self.default_pt_planner
return self._pt_planner_manager.get_pt_planner(pt_planner_id)

def get_all_pt_planners(self):
return self._pt_planner_manager.get_all_pt_planners()

def get_pt_journey_fare(self, loki_pt_journey_fare_id=None):
pt_journey_fare_id = loki_pt_journey_fare_id or self.loki_pt_journey_fare
return self._pt_journey_fare_backend_manager.get_pt_journey_fare(pt_journey_fare_id)
Expand Down
82 changes: 82 additions & 0 deletions source/jormungandr/jormungandr/interfaces/v1/backends_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
from jormungandr import i_manager
from jormungandr.protobuf_to_dict import protobuf_to_dict
from jormungandr.interfaces.v1.StatedResource import StatedResource
from navitiacommon import type_pb2, request_pb2
from jormungandr import exceptions
from collections import defaultdict
import gevent, gevent.pool
from jormungandr import app


class BackendsStatus(StatedResource):
def __init__(self, *args, **kwargs):
super().__init__(self, *args, **kwargs)

def get(self):
regions = i_manager.get_regions()

response = {
'lokis': {},
'krakens': {},
'errors': [],
}

pool = gevent.pool.Pool(app.config.get('BACKENDS_STATUS_GREENLET_POOL_SIZE', 10))

def do(instance_name, pt_planner_type, pt_planner, req):
try:
resp = pt_planner.send_and_receive(req, request_id='backend_status')
status = protobuf_to_dict(resp, use_enum_labels=True)
is_loaded = status.get('status', {}).get('loaded') is True
if not is_loaded:
return instance_name, pt_planner_type, status, 'data is not loaded'
return instance_name, pt_planner_type, status, None
except exceptions.DeadSocketException as e:
return (
instance_name,
pt_planner_type,
None,
'instance {} backend {} did not respond because: {}'.format(
instance_name, pt_planner_type, str(e)
),
)

futures = []

req = request_pb2.Request()
req.requested_api = type_pb2.STATUS

for key_region in regions:
instance = i_manager.instances[key_region]
for pt_planner_type, pt_planner in instance.get_all_pt_planners():
futures.append(pool.spawn(do, instance.name, pt_planner_type, pt_planner, req))

found_err = False
status_code = 200

for future in gevent.iwait(futures):
instance_name, pt_planner_type, status, err = future.get()
found_err |= err is not None
if err:
response['errors'].append(
{'backend_type': pt_planner_type, 'backend_name': instance_name, 'error': err}
)

key = 'krakens' if pt_planner_type == 'kraken' else 'lokis'
status_ = status.get('status', {}) if status is not None else {}
response[key][instance_name] = {
'status': status_.get('status'),
'backend_version': status_.get('navitia_version'),
'start_date': status_.get('start_production_date'),
'end_date': status_.get('end_production_date'),
'loaded': status_.get('loaded'),
'last_load_at': status_.get('last_load_at'),
'last_load_status': status_.get('last_load_status'),
'is_realtime_loaded': status_.get('is_realtime_loaded'),
'last_rt_data_loaded': status_.get('last_rt_data_loaded'),
}

if found_err:
status_code = 503

return response, status_code
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
users,
opg_status,
opg_excluded_zones,
backends_status,
)
from werkzeug.routing import BaseConverter, FloatConverter, PathConverter
from jormungandr.modules_loader import AModule
Expand Down Expand Up @@ -131,6 +132,8 @@ def setup(self):
self.add_resource(Readyness.Readyness, '/readyness', endpoint='readyness')
self.module_resources_manager.register_resource(Index.TechnicalStatus())
self.add_resource(Index.TechnicalStatus, '/status', endpoint='technical_status')
self.add_resource(backends_status.BackendsStatus, '/backends_status', endpoint='backends_status')

lon_lat = '<lon:lon>;<lat:lat>/'
coverage = '/coverage/'
region = coverage + '<region:region>/'
Expand Down
22 changes: 22 additions & 0 deletions source/jormungandr/tests/end_point_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,25 @@ def test_coord_without_region_shouldnt_call_places_nearby(self):
r1 = self.tester.get('v1/coverage/main_routing_test/coord/0.001077974378345651;0.0005839027882705609')
r2 = self.tester.get('v1/coord/0.001077974378345651;0.0005839027882705609')
assert r1.get_json()['address'] == r2.get_json()['address']

def test_backends_status(self):
json_response = self.query("/v1/backends_status")

assert len(json_response['lokis']) == 2
assert len(json_response['krakens']) == 2

for attribute in [
'status',
'backend_version',
'start_date',
'end_date',
'loaded',
'last_load_at',
'last_load_status',
'is_realtime_loaded',
'last_rt_data_loaded',
]:
assert attribute in json_response['lokis']['main_ptref_test']
assert attribute in json_response['krakens']['main_ptref_test']
assert attribute in json_response['lokis']['main_routing_test']
assert attribute in json_response['krakens']['main_routing_test']