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

Optimize storage (serialization and de-serilization) of very large dictionaries inside MongoDB #4846

Merged
merged 107 commits into from
Mar 20, 2021
Merged
Show file tree
Hide file tree
Changes from 64 commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
a93f9c2
Add new JSONDictField which allows us to more efficently store,
Kami Dec 20, 2019
a89d658
Add new JSONDictField which allows us to more efficently store,
Kami Dec 20, 2019
fe5e33d
Add a feature flag for using new json dict field, set it to false
Kami Jan 17, 2020
f0919c9
Use new JSON dict field for dictionaries which can be very large where
Kami Jan 17, 2020
59e87f9
Fix JSONDictEscapedFieldCompatibilityField to get it to work
m4dcoder Feb 22, 2020
2024a1e
Merge branch 'master' into optimize_escaped_dict_fields
Kami Feb 18, 2021
2f969f8
Add a micro-benchmark which comparsed execution save + read times for
Kami Feb 18, 2021
5971302
Add another micro benchmark fixture which represents a dictionary with a
Kami Feb 18, 2021
f19f0fd
Add micro-benchmark for escape_chars() and unescape_chars() and update
Kami Feb 18, 2021
81672f2
Add unit tests for the new fields.
Kami Feb 18, 2021
2a15e8b
Merge branch 'optimize_escaped_dict_fields' of github.com:StackStorm/…
Kami Feb 18, 2021
44bdbad
Handle subclass hack in the micro benchmark itself.
Kami Feb 18, 2021
052fde7
Add some more tests.
Kami Feb 18, 2021
dbc5f3d
Fix invalid / broken test - result is a dict field and not a string.
Kami Feb 18, 2021
424f3d7
Update more affected code to make sure we correctly handle new result
Kami Feb 19, 2021
ff485ca
Also benchmark JSONDict fields with compression.
Kami Feb 19, 2021
6b1abf0
Update docstring.
Kami Feb 19, 2021
89617ff
Add new "finalized_timestamp" field to the Execution and LiveAction
Kami Feb 19, 2021
fa03d2f
Add changelog entry.
Kami Feb 19, 2021
68feb47
Update more affected and broken tests to correctly specify a dict value
Kami Feb 19, 2021
4cb7a1d
Fow now, exclude finalized_timestamp attr from the default CLI outpunt.
Kami Feb 19, 2021
e1d085d
Fix lint.
Kami Feb 19, 2021
d9ad62b
Add python runner action which can be used for testing and timing large
Kami Feb 19, 2021
e20242f
Update changelog.
Kami Feb 19, 2021
95de8ff
Add TODO comment.
Kami Feb 19, 2021
42f70e7
Update the field and implement another approach which uses additional
Kami Feb 19, 2021
8017e2a
Fix lint.
Kami Feb 19, 2021
cbb4cb1
Make tests more robust and less reliant on a specific global state.
Kami Feb 19, 2021
49b4033
Re-generate requiremennts files.
Kami Feb 20, 2021
d93bd9d
Add -x flag to the st2 execution list command.
Kami Feb 20, 2021
c8f4022
Also apply the same field optimizations changes to all the workflows
Kami Feb 21, 2021
88151da
Update changelog.
Kami Feb 21, 2021
a239061
For now, only utilize JSONDictField for fields which are for all
Kami Feb 21, 2021
7cd3ec4
Implement dict value change tracking for our custom JSONDictField.
Kami Feb 21, 2021
82965ef
Update more fields to use the new more efficient dict field.
Kami Feb 21, 2021
eaccea2
Add orquesta workflow action which can be used to test passing large
Kami Feb 21, 2021
9682fac
Update API models to call public field method instead of calling orjson
Kami Feb 21, 2021
bc9e9c2
Update comments, add some tests for the public method.
Kami Feb 21, 2021
2ac3fda
Apply same optimizatons to trigger_instance.payload field.
Kami Feb 21, 2021
49d6134
Add correct file.
Kami Feb 21, 2021
242c676
Update affected tests and API model.
Kami Feb 21, 2021
75ab254
Also add benchmark for model with multiple fields of the same type and
Kami Feb 23, 2021
4933573
Hook micro benchmarks to CI.
Kami Feb 23, 2021
e8745d8
Updat the new field type and make sure we also correctly track changes
Kami Feb 23, 2021
560d616
Use consistent action name.
Kami Feb 23, 2021
147a02b
Simplify the code - instead of having another finalized_timestamp
Kami Feb 24, 2021
405e039
Update st2 execution get command to also display log attribute by
Kami Feb 24, 2021
78f89ab
Update affected tests.
Kami Feb 24, 2021
7810aa8
Also display log attribute on workflow executions.
Kami Feb 25, 2021
b31c006
Update affected tests - live action and action execution timestamp may
Kami Feb 25, 2021
5988b5c
Throw more user-friendly error.
Kami Feb 25, 2021
71791b3
micro-benchmarks task is very slow on CI so for now, only run it on
Kami Feb 26, 2021
1d178df
Fix failing test, remove Python 2 code.
Kami Feb 26, 2021
053bd93
Include the following changes which makes action registration 15-20%
Kami Feb 27, 2021
824c2ea
Merge branch 'master' of github.com:StackStorm/st2 into optimize_esca…
Kami Feb 27, 2021
1a99eee
Fix failing test.
Kami Feb 27, 2021
ca49b10
Fix rst syntax.
Kami Feb 27, 2021
4289b9e
Pin mail-parser test dep to the latest version so tests work correctly.
Kami Feb 27, 2021
9f0a6ba
Update more places in the code where we only work with simple / native
Kami Feb 27, 2021
4793ba3
Update nose tests target to exclude resource registrar debug log
Kami Feb 27, 2021
dbc1460
Use correct path for pip cache dir.
Kami Feb 27, 2021
af961fb
Merge branch 'master' of github.com:StackStorm/st2 into optimize_esca…
Kami Mar 6, 2021
64dbe5a
Use lazy import since right now zstandard is only used for tests and
Kami Mar 6, 2021
167ca3f
Add a comment to custom yaml_safe_load() method.
Kami Mar 6, 2021
8902d06
Better handle scenario when log attribute is already formatted.
Kami Mar 7, 2021
6eabd5b
Add workaround for issue i've seen very seldomly on ci with trigger
Kami Mar 7, 2021
2c2cb74
Make sure we don't call unescape_chars() on the JSONDictField field
Kami Mar 7, 2021
93d859c
Update changelog.
Kami Mar 7, 2021
2ea37db
Remove unused options.
Kami Mar 7, 2021
0f293ee
Add additional timer metrics to the action runner which will provide
Kami Mar 12, 2021
a46831e
Merge branch 'master' of github.com:StackStorm/st2 into optimize_esca…
Kami Mar 12, 2021
c8c3b91
Merge branch 'master' of github.com:StackStorm/st2 into optimize_esca…
Kami Mar 14, 2021
b2ed03b
Remove incorrect log message which was causing unncessary log churn in
Kami Mar 14, 2021
9feb81e
Also json instead of orjson so action can also be used with older
Kami Mar 15, 2021
9f4f523
Store "result_size field on the ActionExecutionDB.
Kami Mar 15, 2021
d0f0d78
Add new WIP API endpoint for returning / downloading raw action
Kami Mar 15, 2021
b0dea78
Also add support for compressing and pretty printing the raw response.
Kami Mar 16, 2021
756b916
Update URL path, add tests.
Kami Mar 16, 2021
a47461b
Update "result_size" field for action execution and live action DB model
Kami Mar 16, 2021
2005126
Move calculation and setting of the result_size field to the
Kami Mar 16, 2021
086be02
Add changelog entry.
Kami Mar 16, 2021
8e0c312
Re-generate api spec.
Kami Mar 16, 2021
cd9eba7
Fix typo.
Kami Mar 16, 2021
1a932ca
Fix failing test.
Kami Mar 16, 2021
e72215f
Merge branch 'master' of github.com:StackStorm/st2 into optimize_esca…
Kami Mar 16, 2021
9e336d8
Fix merge conflicts.
Kami Mar 16, 2021
d373cf5
Fix test method name.
Kami Mar 16, 2021
224dfba
Merge branch 'master' into optimize_escaped_dict_fields
Kami Mar 18, 2021
3cc71ef
Add micro benchmark which times saving and reading large string value
Kami Mar 18, 2021
ac4efbd
Merge branch 'optimize_escaped_dict_fields' of github.com:StackStorm/…
Kami Mar 18, 2021
051a691
Fix --with-schema flag which didn't work and threw and exception under
Kami Mar 19, 2021
94b6298
Update CLI to use C version of the YAML safe dumper when pretty
Kami Mar 19, 2021
d1df1cd
Clarify the comment.
Kami Mar 19, 2021
b13c195
Add workaround for weird failure on CI which should not be fatatal.
Kami Mar 19, 2021
51f811c
Log a warning message if pyyaml C bindings are not available since it
Kami Mar 19, 2021
4672495
Upgrade orjson to latest stable version.
Kami Mar 19, 2021
a25efa6
Update out of date st2client setup.py metadata.
Kami Mar 19, 2021
bdd8e3c
Add a comment on libyaml availability.
Kami Mar 19, 2021
a098315
Update more code to use orjson and C versions of yaml load/dump
Kami Mar 19, 2021
e818158
Use fast dict copy.
Kami Mar 19, 2021
48d612d
For performance reasons, use udatetime library for parsing rfc3339 /
Kami Mar 19, 2021
71ffb1a
ujson is not only used for tests / benchmarks so move it to
Kami Mar 19, 2021
46ba2c9
Fix typo.
Kami Mar 19, 2021
a27245f
Add TODO comment.
Kami Mar 19, 2021
1a91394
Fix affected test.
Kami Mar 19, 2021
cbd0259
Apply suggestions from code review
Kami Mar 20, 2021
3b47856
Fix syntax, add comments.
Kami Mar 20, 2021
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
4 changes: 4 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ jobs:
- name: 'Unit Tests'
task: 'ci-unit'
python-version: '3.6'
# This job is slow so we only run in on a daily basis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Github actions works much better if we use more workflows because you can only restart jobs at the Workflow level, not per job.

So, when we add the benchmark job, it should be in a separate Workflow file.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ack. I will likely add it in the future to run once a week or something since the job is very slow on CI (~30 minutes).

# - name: 'Micro Benchmarks'
# task: 'micro-benchmarks'
# python-version: '3.6'
# Integration tests are not working yet, still done in Travis
# - name: 'Integration Tests'
# task: 'ci-integration'
Expand Down
82 changes: 80 additions & 2 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,48 @@ Changed

Contributed by @Kami.

* Add new ``-x`` argument to the ``st2 execution get`` command which allows
``result`` field to be excluded from the output. (improvement) #4846

* Underlying database field type and storage format for the ``Execution`` and ``LiveAction``
database models has changed.

Contributed by @Kami.

This new format is much faster and efficient than the previous one. Users with larger executions
(executions with larger results) should see the biggest improvements, but the change also scales
down so there should also be improvements when reading and writing executions with small and
medium sized results.

Our micro and end to benchmarks have shown improvements up to 10x for write path (storing model
in the database) and up to 6x for the read path.

To put things into perspective - with previous version, running a Python runner action which
returns 8 MB result would take around ~18 seconds total, but with this new storage format, it
takes around 2 seconds (in this context, duration means the from the time the execution was
scheduled to the time the execution model and result was written and available in the database).

Overall performance improvement doesn't just mean large decrease in those operation timings, but
also large overall reduction of CPU usage - previously serializing large results was a CPU
intensive time since it included tons of conversions and transformations back and forth.

The actual change should be fully opaque and transparent to the end users - it's purely a
field storage implementation detail and the code takes care of automatically handling both
formats when working with those object.

Same field data storage optimizations have also been applied to workflow related database models
which should result in the same performance improvements for Orquesta workflows which pass larger
data sets / execution results around.

Trigger instance payload field has also been updated to use this new field type which should
result in lower CPU utilization and better throughput of rules engine service when working with
triggers with larger payloads.

This should address a long standing issue where StackStorm was reported to be slow and CPU
inefficient with handling large executions. (improvement) #4846

Contributed by @Kami.

3.4.0 - March 02, 2021
----------------------

Expand All @@ -29,8 +71,9 @@ Added
* Added st2-auth-ldap pip requirements for LDAP auth integartion. (new feature) #5082
Contributed by @hnanchahal

* Added --register-recreate-virtualenvs flag to st2ctl reload to recreate virtualenvs from scratch.
(part of upgrade instructions) [#5167]
* Added --register-recreate-virtualenvs flag to st2ctl reload to recreate virtualenvs from
scratch. (part of upgrade instructions) #5167

Contributed by @winem and @blag

Changed
Expand All @@ -55,6 +98,39 @@ Changed

* Updated cryptography dependency to version 3.3.2 to avoid CVE-2020-36242 (security) #5151

* Update ``st2 execution get <id>`` command to also display execution ``log`` attribute which
includes execution state transition information.

By default ``end_timestamp`` attribute and ``duration`` attribute displayed in the command
output only include the time it took action runner to finish running actual action, but it
doesn't include the time it it takes action runner container to fully finish running the
execution - this includes persisting execution result in the database.

For actions which return large results, there could be a substantial discrepancy - e.g.
action itself could finish in 0.5 seconds, but writing data to the database could take
additional 5 seconds after the action code itself was executed.

For all purposes until the execution result is persisted to the database, execution is
not considered as finished.

While writing result to the database action runner is also consuming CPU cycles since
serialization of large results is a CPU intensive task.

This means that "elapsed" attribute and start_timestamp + end_timestamp will make it look
like actual action completed in 0.5 seconds, but in reality it took 5.5 seconds (0.5 + 5 seconds).

Log attribute can be used to determine actual duration of the execution (from
start to finish). (improvement) #4846

Contributed by @Kami.

* Various internal improvements (reducing number of DB queries, speeding up YAML
parsing, using DB object cache, etc.) which should speed up pack action
registration between 15-30%. This is especially pronounced with packs which
have a lot of actions (e.g. aws one). (improvement) #4846

Contributed by @Kami.

Fixed
~~~~~

Expand Down Expand Up @@ -143,6 +219,7 @@ Added

Changed
~~~~~~~

* Switch to MongoDB ``4.0`` as the default version starting with all supported OS's in st2
``v3.3.0`` (improvement) #4972

Expand All @@ -165,6 +242,7 @@ Changed

Fixed
~~~~~

* Fixed a bug where `type` attribute was missing for netstat action in linux pack. Fixes #4946

Reported by @scguoi and contributed by Sheshagiri (@sheshagiri)
Expand Down
22 changes: 19 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,17 @@ ifndef PYLINT_CONCURRENCY
PYLINT_CONCURRENCY := 1
endif

NOSE_OPTS := --rednose --immediate --with-parallel --nocapture
# NOTE: We exclude resourceregistrar DEBUG level log messages since those are very noisy (we
# loaded resources for every tests) which makes tests hard to troubleshoot on failure due to
# pages and pages and pages of noise.
NOSE_OPTS := --rednose --immediate --with-parallel --nocapture --logging-filter=-st2.st2common.bootstrap
Kami marked this conversation as resolved.
Show resolved Hide resolved

ifndef NOSE_TIME
NOSE_TIME := yes
endif

ifeq ($(NOSE_TIME),yes)
NOSE_OPTS := --rednose --immediate --with-parallel --with-timer --nocapture
NOSE_OPTS := --rednose --immediate --with-parallel --with-timer --nocapture --logging-filter=-st2.st2common.bootstrap
NOSE_WITH_TIMER := 1
endif

Expand Down Expand Up @@ -261,7 +264,7 @@ check-python-packages-nightly:
done

.PHONY: ci-checks-nightly
ci-checks-nightly: check-python-packages-nightly
ci-checks-nightly: check-python-packages-nightly micro-benchmarks

.PHONY: checklogs
checklogs:
Expand Down Expand Up @@ -516,6 +519,19 @@ compilepy3:
find ${ROOT_DIR}/st2common/st2common/ \( -name \*.py ! -name router\.py -name \*.py \) -type f -print0 | xargs -0 cat | grep st2stream; test $$? -eq 1
find ${ROOT_DIR}/st2common/st2common/ -name \*.py -type f -print0 | xargs -0 cat | grep st2exporter; test $$? -eq 1

.PHONY: micro-benchmarks
micro-benchmarks: requirements .micro-benchmarks

.PHONY: .micro-benchmarks
.micro-benchmarks:
@echo
@echo "==================== micro-benchmarks ===================="
@echo
. $(VIRTUALENV_DIR)/bin/activate; pytest --benchmark-only --benchmark-name=short --benchmark-columns=min,max,mean,stddev,median,ops,rounds --benchmark-group-by=group,param:fixture_file -s -v st2common/benchmarks/micro/test_mongo_field_types.py -k "test_save_large_execution"
. $(VIRTUALENV_DIR)/bin/activate; pytest --benchmark-only --benchmark-name=short --benchmark-columns=min,max,mean,stddev,median,ops,rounds --benchmark-group-by=group,param:fixture_file -s -v st2common/benchmarks/micro/test_mongo_field_types.py -k "test_read_large_execution"
. $(VIRTUALENV_DIR)/bin/activate; pytest --benchmark-only --benchmark-name=short --benchmark-columns=min,max,mean,stddev,median,ops,rounds --benchmark-group-by=group,param:fixture_file -s -v st2common/benchmarks/micro/test_mongo_field_types.py -k "test_save_multiple_fields"


.PHONY: .cleanmongodb
.cleanmongodb:
@echo "==================== cleanmongodb ===================="
Expand Down
2 changes: 2 additions & 0 deletions conf/st2.dev.conf
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Config used by local development environment (tools/launch.dev.sh)
[database]
host = 127.0.0.1
use_json_dict_field = True
json_dict_field_backend = ujson

[api]
# Host and port to bind the API server.
Expand Down
2 changes: 1 addition & 1 deletion contrib/core/requirements-tests.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
mail-parser>=3.9.1,<3.10.0
mail-parser==3.15.0
42 changes: 11 additions & 31 deletions contrib/core/tests/test_action_sendmail.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import tempfile
import socket

import six
import mock
import mailparser

Expand Down Expand Up @@ -126,20 +125,12 @@ def test_sendmail_utf8_subject_and_body(self):
"attachments": "",
}

if six.PY2:
expected_body = (
"Hello there 😃😃.\n"
"<br><br>\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)
else:
expected_body = (
"Hello there \\U0001f603\\U0001f603.\n"
"<br><br>\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)
expected_body = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we've kept the code from the if - which if I read it was only if we were running on python2, so should we not have kept the else logic?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above.

"Hello there 😃😃.\n"
"<br><br>\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)

status, _, email_data, message = self._run_action(
action_parameters=action_parameters
Expand Down Expand Up @@ -167,18 +158,11 @@ def test_sendmail_utf8_subject_and_body(self):
"attachments": "",
}

if six.PY2:
expected_body = (
"Hello there 😃😃.\n\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)
else:
expected_body = (
"Hello there \\U0001f603\\U0001f603.\n\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)
expected_body = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we've kept the code from the if - which if I read it was only if we were running on python2, so should we not have kept the else logic?

Copy link
Member Author

@Kami Kami Mar 19, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The version of the used library has also been changed / upgraded so now the behavior is different / more correct.

To clarify - we don't want to use escape sequences since that is Python specific and would not display correctly in the email clients, etc.

I assume we just did that change when working on Python 3 support a long time ago since it was the easiest, but technically not the most correct one :)

"Hello there 😃😃.\n\n"
"This message was generated by StackStorm action "
"send_mail running on %s" % (HOSTNAME)
)

status, _, email_data, message = self._run_action(
action_parameters=action_parameters
Expand Down Expand Up @@ -271,10 +255,6 @@ def _run_action(self, action_parameters):
email_data = result["stdout"]
email_data = email_data.split("\n")[:-2]
email_data = "\n".join(email_data)

if six.PY2 and isinstance(email_data, six.text_type):
email_data = email_data.encode("utf-8")

message = mailparser.parse_from_string(email_data)
else:
email_data = None
Expand Down
11 changes: 11 additions & 0 deletions contrib/examples/actions/orquesta-data-flow-large-data.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: orquesta-data-flow-large-data
description: A basic workflow which passes large JSON data around.
runner_type: orquesta
entry_point: workflows/orquesta-data-flow-large-data.yaml
enabled: true
parameters:
file_path:
type: string
required: true
description: "Path to the JSON fixture file to use."
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
name: python_runner_load_and_print_fixture
description: Action which loads provided JSON fixture file, parses it and returns it as an action result. Useful when testing and benchmarking execution save timing.
runner_type: "python-script"
enabled: true
entry_point: pythonactions/load_and_print_fixture.py
parameters:
file_path:
type: "string"
required: true
description: "Path to the JSON fixture file to use."
12 changes: 12 additions & 0 deletions contrib/examples/actions/pythonactions/load_and_print_fixture.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import orjson

from st2common.runners.base_action import Action


class LoadAndPrintFixtureAction(Action):
def run(self, file_path: str):
with open(file_path, "r") as fp:
content = fp.read()

data = orjson.loads(content)
return data
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
version: 1.0

description: A basic workflow which passes large data around.

input:
- file_path
- b1: <% ctx().file_path %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really? You can define vars in input that are not defined in the input parameters metadata? 🤯
I've always used vars for that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I actually just used an existing sample workflow for reference :D


vars:
- a2: <% ctx().b1 %>
- b2: <% ctx().a2 %>

output:
- a5: <% ctx().b4 %>
- b5: <% ctx().a5 %>

tasks:
task1:
action: core.echo
input:
message: <% ctx().b2 %>
next:
- when: <% succeeded() %>
publish:
- a3: <% result().stdout %>
- b3: <% ctx().a3 %>
do: task2
task2:
action: examples.load_and_print_fixture
input:
file_path: <% ctx().file_path %>
next:
- when: <% succeeded() %>
publish: a4=<% result().result %> b4=<% ctx().a4 %>
do: task3
task3:
action: core.noop
1 change: 1 addition & 0 deletions fixed-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,5 @@ python-dateutil==2.8.0
python-statsd==2.1.0
prometheus_client==0.1.1
ujson==1.35
orjson==3.4.8
zipp>=0.5,<=1.0.0
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ networkx==1.11
nose
nose-parallel==0.3.1
nose-timer==0.7.5
orjson==3.4.8
oslo.config<1.13,>=1.12.1
oslo.utils<5.0,>=4.0.0
paramiko==2.7.1
Expand Down
Loading