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

stop shuffling ranger_handles and incident_types #1368

Closed
wants to merge 1 commit into from

Conversation

srabraham
Copy link
Member

Currently those fields under an incident get randomly sorted in the API response, since a frozenset is unordered. This surfaces on the incidents page, where ranger handles and incident types both show up in a random order. That's kind of weird.

This is a pretty simple fix for that, which makes the API response consistent.

I've looked through the Git history a fair bit to see why frozensets were used in the first place. I'm fairly confident it was just because we needed an immutable, hashable collection with duplicates removed. This new way achieves those same ends too, but it also maintains ordering.
https://github.com/search?q=repo%3Aburningmantech%2Franger-ims-server+frozenset&type=commits

#1348
#373

Copy link
Contributor

github-actions bot commented Nov 5, 2024

⚠️ Optional matrix job Py:3.14.0-alpha.1 - ubuntu-latest failed ⚠️

  • tox prefix: test
  • exit status: 1

Currently those fields under an incident get randomly sorted in
the API response, since a frozenset is unordered. This surfaces on
the incidents page, where ranger handles and incident types both
show up in a random order. That's kind of weird.

This is a pretty simple fix for that, which makes the API response
consistent.

I've looked through the Git history a fair bit to see why frozensets
were used in the first place. I'm fairly confident it was just
because we needed an immutable, hashable collection with duplicates
removed. This new way achieves those same ends too, but it also
maintains ordering.
https://github.com/search?q=repo%3Aburningmantech%2Franger-ims-server+frozenset&type=commits
@srabraham srabraham requested review from wsanchez and mikeburg and removed request for wsanchez and mikeburg November 5, 2024 13:35
@srabraham srabraham marked this pull request as draft November 5, 2024 15:02
@wsanchez
Copy link
Member

wsanchez commented Nov 5, 2024

I like to be rather minimalist in terms of API promises. If what you need from endpoint E is an iterable of X, I will give you something that you can sequence through but no other promises. If you want that sorted/mutable/whatever, do that yourself, yo.

That said, for a JSON API response, there is merit to at least guaranteeing the same order for the same request, so that responses are cacheable and hashable, which is desirable on the HTTP side. So I'm OK with the JSON serializer doing this.

Fixing it here in the model objects is going a step further, in which the endpoints are giving you sorted data kind of by accident. If that's a thing the endpoints want to ensure, they should be sorting there.

So my suggestion would be to do your sorting here.

@srabraham
Copy link
Member Author

srabraham commented Nov 5, 2024

Fixing it here in the model objects is going a step further, in which the endpoints are giving you sorted data kind of by accident. If that's a thing the endpoints want to ensure, they should be sorting there.

So my suggestion would be to do your sorting here.

Not quite though. This PR doesn't sort the iterable passed to freezeStrings; it just doesn't randomize the order of that iterable. Prior to this PR, freezeStrings was taking an ordered iterable and returning something with a randomish order, since a frozenset is unordered. See below for example code

I think we might agree that this is a weird place to be mucking with data like this, and I'd be totally happy to not do this here (i.e. no deduplicating and no un-ordering). I'm not sure that frozensets are all that useful at all.

input = ["first", "second", "third", "fourth"]

# old way, shuffles the input
print(", ".join(frozenset(input)))
# second, first, fourth, third

# new way, maintains insertion order
input = ["first", "second", "third", "fourth"]
dict = {key: None for key in input}
print(tuple(key for key in dict))
# ('first', 'second', 'third', 'fourth')

@srabraham
Copy link
Member Author

I'm going to close this PR, since it'll be easier to start over. See the new comment over here for what I think is the right approach: #1348 (comment)

@srabraham srabraham closed this Nov 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants