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

Move all APIs to use the Twisted-managed connection #184

Merged
merged 4 commits into from
Jun 27, 2019

Conversation

jeremycline
Copy link
Member

@jeremycline jeremycline commented Jun 10, 2019

This introduces crochet[0], a small library designed to make it easy to
provide synchronous APIs using asynchronous Twisted APIs. This modifies
the fedora_messaging.api.consume and fedora_messaging.api.publish
calls to use the Twisted protocol.

There are several advantages here:

  1. The synchronous and asynchronous APIs use the same code which means
    there's fewer opportunities for them to differ in behavior and less
    code to maintain.

  2. Both APIs didn't really work well because they could not heartbeat in
    the background. This lets them do so because the connection is
    handled in Twisted in a separate crochet-managed thread. While the
    performance improvements are likely modest, it won't lead to so many
    TCP connections being killed by firewalls or the broker.

The downside is it introduces the complexity of threads to the API which
makes it less obvious what is going on.

There are a few minor changes here which slightly change the APIs:

  1. Publishing now raises a PublishTimeout when the timeout is reached
    (30 seconds by default).

  2. Previously, the Twisted consume API did not validate arguments like
    the synchronous version did, so it now raises a ValueError on invalid
    arguments instead of crashing in some undefined way.

  3. Calling publish from the Twisted reactor thread now raises an
    exception instead of blocking the reactor thread.

Although all these are small changes, I think this should be in a 2.0
release. In practice I don't think any of these issues will bite anyone
so upgrading shouldn't be a problem for anyone.

This does not move the CLI back to the synchronous API (yet).

This fixes #171 by unifying the async and sync APIs.

@jeremycline jeremycline added no-mergify Add this label to pull requests to stop automatic merging backwards-incompatible Indicates an issue or pull request is backwards-incompatible labels Jun 10, 2019
@jeremycline jeremycline force-pushed the crochet-sync-api branch 3 times, most recently from b5108aa to ebcf8a4 Compare June 21, 2019 19:59
@codecov-io
Copy link

codecov-io commented Jun 21, 2019

Codecov Report

Merging #184 into master will increase coverage by 0.53%.
The diff coverage is 95.77%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #184      +/-   ##
==========================================
+ Coverage   94.89%   95.42%   +0.53%     
==========================================
  Files          14       13       -1     
  Lines        1450     1312     -138     
  Branches      189      158      -31     
==========================================
- Hits         1376     1252     -124     
+ Misses         55       45      -10     
+ Partials       19       15       -4
Impacted Files Coverage Δ
fedora_messaging/api.py 100% <100%> (ø) ⬆️
fedora_messaging/exceptions.py 92.85% <100%> (+0.17%) ⬆️
fedora_messaging/testing.py 100% <100%> (ø) ⬆️
fedora_messaging/twisted/protocol.py 93.2% <77.77%> (+3.07%) ⬆️
fedora_messaging/twisted/factory.py 93.41% <88.46%> (-0.75%) ⬇️
fedora_messaging/twisted/service.py 97.6% <97.14%> (+0.69%) ⬆️
fedora_messaging/message.py 95.45% <0%> (-1.24%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2893dac...ebae73e. Read the comment docs.

@jeremycline jeremycline changed the title WIP: Move all APIs to use the Twisted-managed connection Move all APIs to use the Twisted-managed connection Jun 21, 2019
@jeremycline jeremycline force-pushed the crochet-sync-api branch 2 times, most recently from 8871dae to 0746d68 Compare June 21, 2019 22:50
@jeremycline
Copy link
Member Author

@abompard I squashed the one known issue I had with this PR and I think it's ready for an initial review.

Copy link
Member

@abompard abompard left a comment

Choose a reason for hiding this comment

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

Woah. Thanks a lot, it looks great! Just a few comments.

# used in the code base which is equivalent to 68 years, which I believe to
# be an acceptably long amount of time. If you hit this limit you
# should know that I'll feel no sympathy for you as I'll almost
# certainly be dead.
Copy link
Member

Choose a reason for hiding this comment

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

😆


@pytest_twisted.inlineCallbacks
def delayed_publish():
"""Let's the consumer have time to setup."""
Copy link
Member

Choose a reason for hiding this comment

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

Parse error here. Maybe a 's to remove?

sock.bind(("", 0))
config.conf["amqp_url"] = "amqp://localhost:{port}/".format(
port=sock.getsockname()[1]
)
Copy link
Member

Choose a reason for hiding this comment

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

Nice!

client = yield serv.getFactory().whenConnected()
channel = yield client._allocate_channel()
assert channel._delivery_confirmation is True
serv.stopService()
Copy link
Member

Choose a reason for hiding this comment

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

Should the startService and stopService be yielded?

Copy link
Member Author

Choose a reason for hiding this comment

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

startService doesn't return a deferred, but you're right about stopService. Fixed.

"exclusive": False,
"auto_delete": False,
"arguments": {"x-expires": 60 * 1000},
}
Copy link
Member

Choose a reason for hiding this comment

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

This definition is re-used plenty of times throughout the file, maybe it could be factored.

queues = [
{
"queue": queue,
"auto_delete": True,
Copy link
Member

Choose a reason for hiding this comment

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

This was false before, is there a reason to set it to True here?

Copy link
Member Author

Choose a reason for hiding this comment

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

It looks like it was always true and I just didn't change it when I merged the two integration test sets, I've fixed it and will also pull out the declaration into a fixture.

@jeremycline
Copy link
Member Author

Okay, I've addressed the PR comments. If you're happy with the general shape of things, I'll resolve the merge conflicts and see about adding a bit more test coverage and we should be ready. I already packaged crochet for Fedora and we can built it in the infra repository for epel7.

@abompard
Copy link
Member

Yeah I'm happy with the state of things, and happy to have fewer codepaths :-) Thanks!

@jeremycline jeremycline force-pushed the crochet-sync-api branch 2 times, most recently from 1e38a9d to ca4b0f4 Compare June 25, 2019 19:49
This introduces crochet[0], a small library designed to make it easy to
provide synchronous APIs using asynchronous Twisted APIs. This modifies
the `fedora_messaging.api.consume` and `fedora_messaging.api.publish`
calls to use the Twisted protocol.

There are several advantages here:

1. The synchronous and asynchronous APIs use the same code which means
   there's fewer opportunities for them to differ in behavior and less
   code to maintain.

2. Both APIs didn't really work well because they could not heartbeat in
   the background. This lets them do so because the connection is
   handled in Twisted in a separate crochet-managed thread. While the
   performance improvements are likely modest, it won't lead to so many
   TCP connections being killed by firewalls or the broker.

The downside is it introduces the complexity of threads to the API which
makes it less obvious what is going on.

There are a few minor changes here which slightly change the APIs:

1. Publishing now raises a PublishTimeout when the timeout is reached
   (30 seconds by default).

2. Previously, the Twisted consume API did not validate arguments like
   the synchronous version did, so it now raises a ValueError on invalid
   arguments instead of crashing in some undefined way.

3. Calling publish from the Twisted reactor thread now raises an
   exception instead of blocking the reactor thread.

Although all these are small changes, I think this should be in a 2.0
release. In practice I don't think any of these issues will bite anyone
so upgrading shouldn't be a problem for anyone.

This does not move the CLI back to the synchronous API (yet).

Signed-off-by: Jeremy Cline <jcline@redhat.com>
Signed-off-by: Jeremy Cline <jcline@redhat.com>
Signed-off-by: Jeremy Cline <jcline@redhat.com>
Signed-off-by: Jeremy Cline <jcline@redhat.com>
@jeremycline jeremycline removed the no-mergify Add this label to pull requests to stop automatic merging label Jun 25, 2019
@jeremycline
Copy link
Member Author

jeremycline commented Jun 25, 2019

Okay, I've rebased and added a couple more tests. The lack of coverage is in a compatibility block for EL7 which is difficult to test in CI, but would be covered by tests run in EL7. I'm inclined to leave them as-is until we drop support for that. The other spot I couldn't easily get coverage was in the publish code that handled connection errors during the publish. I could mock it all out and test that, but I'd prefer a test against an actual broker, I've just not come up with a neat way to do it yet.

Anyway, I think this is ready for a final look over and merge. I'll see about getting the publish CLI branch I have rebased and pushed since that will include a few backwards incompatible code changes to dump/load format of messages (which I think no one is using). I'll also see about dropping the old twisted protocol code since it's a major release and I'm also pretty sure no one is using it.

Copy link
Member

@abompard abompard left a comment

Choose a reason for hiding this comment

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

Yeah, I think this is ready for merging.
About the old twisted API, I know at least one of the fedmsg-migration-tools scripts use one of those APIs, probably the verify-missing service.

@mergify mergify bot merged commit 1c6c22d into fedora-infra:master Jun 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backwards-incompatible Indicates an issue or pull request is backwards-incompatible
Projects
None yet
Development

Successfully merging this pull request may close these issues.

api.consume against fedora endpoint hits permissions issue
3 participants