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

Refactor the initial raw decoding #168

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

comstud
Copy link
Contributor

@comstud comstud commented Oct 21, 2023

  • clean up the Raw HTTP route, move code to raw_decoder.
  • move device location tracking to its own package/struct
  • create a map of method -> decode function, minimum level required
    • we don't need level 30 for everything
    • map will be more efficient than big switch/case
    • decode functions take in the proto and its metadata like device uuid, account, etc. This will allow us to pass information deeper for things like shiny stats which will require tracking accounts.

@comstud comstud marked this pull request as draft October 21, 2023 09:00
@comstud
Copy link
Contributor Author

comstud commented Oct 21, 2023

Untested yet, so marked as draft. Early feedback is welcome, though.

}
}

func (dec *rawDecoder) Decode(ctx context.Context, protoData *ProtoData, decodeFn func(context.Context, *Proto)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I intend to move the rest of the raw decoding out of 'main' and into this package, but for now this just takes a pointer to main's 'decode' function, shared between the http and grpc apis. This MR already does enough. I'll save more code shuffling for a follow-up.

@comstud
Copy link
Contributor Author

comstud commented Oct 21, 2023

I am running a version of this that is simply rebased on top of the the 'stats collector' PR that I've also made.

If any of this is approved, I would suggest we take a look at the stats collector PR first and land that. Then I can push up the rebased version of this.

And I have the next commit ready that moves the rest of decoding out of main and into the raw_decoder. But it is rebased on top of the rebased version of this... So I'm not going to PR that yet. But if interested in seeing where this is going, this is the commit: comstud@11866f0

)

type RawDecoder interface {
GetProtoDataFromHTTP(http.Header, []byte) (*ProtoData, error)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do alternative ways of receiving data make sense to put in the same interface?
Surely we just get the data into a standard for (ProtoData I guess) and then pass on to a common processor?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this doesn't feel right to me, either. Not sure what I was smoking that night. Starting to refresh myself with what I did here.. since this was 1.5mo ago. :) I've been running with this patch this whole time, though. I'll fix this.

}

func (pd ProtoData) Lat() float64 {
l := len(pd.Protos)
Copy link
Collaborator

Choose a reason for hiding this comment

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

I've not followed exactly when this is called - for the standard MITM send, the lat/lon at the top of the body indicates where the calls were made from (and where processing rules are applied against); individual lat/lon on items aren't really used. I know this is what pogodroid does, but this is the exception I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I also believe PD to be the exception, but since this object is the general object being built by the /raw decoder, it sort of needs to support it. Although, I don't remember how this is being used either. I will look it over.

for _, proto := range protoData.Protos {
// provide independent cancellation contexts for each proto decode
ctx, cancel := context.WithTimeout(ctx, dec.decodeTimeout)
decodeFn(ctx, &proto)
Copy link
Collaborator

Choose a reason for hiding this comment

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

We used to call each decoder in their own go-routine; however this caused too much tripping up and waiting on the striped mutex - since you might have responses that affect the same objects (eg during questing etc).
You also see some MITM include the gmo and the encounters in the same raw (even though this can't be how they were executed against the game).
Having independent cancellation is fine; originally intention was to be quite strict to not end in a backlog situation (which RDM is very common for when overloaded) - where you never catch up because you have so many concurrent decodes happening.

Copy link
Contributor Author

@comstud comstud Oct 26, 2023

Choose a reason for hiding this comment

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

This is actually copy/paste from existing code. But It looks like we don't need to make a new context for every single call here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(I'll reply to the other comments when I can )

@jfberry
Copy link
Collaborator

jfberry commented Oct 26, 2023

I'm in favour of this refactor (and breaking out the decoders) - the split between the decode module and main has always been uncomfortable - it gradually evolved from golbat the prototype into golbat the production code.
A rethink is very worthwhile

* clean up the Raw HTTP route, move code to raw_decoder.
* move device location tracking to its own package/struct
* create a map of method -> decode function, minimum level required
  * we don't need level 30 for everything
  * map will be more efficient than big switch/case
  * decode functions take in the proto and its metadata like
    device uuid, account, etc. This will allow us to pass
    information deeper for things like shiny stats which will
    require tracking accounts.
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