Skip to content

Expose torrent Peer status updates#987

Merged
anacrolix merged 15 commits intoanacrolix:masterfrom
nimbleape:torrent-peer-status-updates
Mar 18, 2025
Merged

Expose torrent Peer status updates#987
anacrolix merged 15 commits intoanacrolix:masterfrom
nimbleape:torrent-peer-status-updates

Conversation

@marcovidonis
Copy link
Collaborator

Provide updates on peer status which include peer ID, ok status, and an error message. This can be useful for the client to be notified of errors when running a connection after handshake.

Updates are sent via channels to Observers, which are set up by the client in config.

marcovidonis and others added 4 commits October 15, 2024 11:52
* basic observer framework
* connects to a valid tracker
* added observer channel for announce status
* set up Peer Connection status Observers
* add PeerConn test: connection established
* added Observers factory method
* Added Event to AnnounceStatus, with embedded TrackerStatus
* state updates must be non-blocking
* add unit tests on PeerConn Observer status reading
* add test and debug log on dropped connection
* add PeerID check to test

---------

Co-authored-by: Parker Whittle <pwhittle@medicom.us>
@anacrolix
Copy link
Owner

I'm not sure about this one. I don't think channels are a good way to handle events unless there's explicit concurrency cooperation required. In the case here where we are updating status information, there's no cooperation, we're just telling users of events. I think I started setting up https://pkg.go.dev/github.com/anacrolix/torrent#Callbacks as a way to handle various events that occur in the client. In particular if you wanted to have a subset of this exposed to various subpackages, like trackers, webtorrent etc. you would create a callback struct for each of those and embed it in the larger one in the client. Having synchronous events lets the user act on or even alter behaviour as appropriate. As for the various status objects, what do you think of just exposing those internal types where possible instead? I believe I started this process for Peer, PeerConn, Torrent and a few others, and their public API is mixed but could be extended.

In general I think introducing observers, and meta types to track their state creates new API contracts that are particularly hard to navigate around. I could be completely wrong but it just doesn't feel right. There have been plenty of bad API choices in anacrolix/torrent to date that I'm stuck with.

@marcovidonis
Copy link
Collaborator Author

Thanks for getting back to me on this. I generally like channels as I feel I can give real-time updates as things happen, but I see your point and I'll look into changing this into callbacks (when I get some time).
As for exposing internal types, I think I picked up the pattern of writing getter functions early on, and only recently learned that it's actually not a recommended pattern! So yes, I totally agree with just exposing those types.

@marcovidonis
Copy link
Collaborator Author

@anacrolix I gave this some thought and I've realised that my initial setup, with different observers receiving slightly different status updates (PeerStatus, TrackerStatus and AnnounceStatus) was not really flexible, and probably not the right way to go. So I've thought of taking a different approach with callbacks, and added a StatusUpdated cb that will send various types of events. Then it will be up to the user to filter the events they're interested in handling, and how, by appending their function(s) to StatusUpdated.

I think this could be a useful way to inform the user of different types of events that might happen, and which they might want to react to. This would be in addition to the existing callbacks, which are more specific, and it would make it quite simple to add new events in the future.

I've started the work in this direction in the last 2 commits. I'd be interested to know if you think this is a viable approach, so then I can look at replacing all the observers properly.

@anacrolix
Copy link
Owner

Sorry for the delay on this. I think you're heading in my preferred direction. Let me know if you want the whole PR reviewed.

Thanks for your fantastic contributions

@marcovidonis
Copy link
Collaborator Author

@anacrolix, it took me a while, but I finally got around to completing this work on status update callbacks, with updated tests. To test callbacks, I used channels to keep the test up until events are received properly: Please let me know if you're ok with this approach, or if there's another way that you prefer.

All tests pass locally on my machine, but they fail here because of #999.

@marcovidonis marcovidonis requested a review from anacrolix March 11, 2025 16:17
@anacrolix
Copy link
Owner

I'll check it out thoroughly shortly.

If the CI fixes are missing I'll merge them in unless someone beats me to it.

@anacrolix
Copy link
Owner

There's a few changes I'd make but I don't want to block this further. I'll sort them out if it comes up as an issue.

@anacrolix anacrolix merged commit 3a656a2 into anacrolix:master Mar 18, 2025
2 of 10 checks passed
@anacrolix
Copy link
Owner

I think some data races slipped through on this one.

@anacrolix
Copy link
Owner

Fixed in 28651a4.

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