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

callback_port config compiled into plug at compile time #174

Open
LostKobrakai opened this issue Jan 8, 2023 · 10 comments
Open

callback_port config compiled into plug at compile time #174

LostKobrakai opened this issue Jan 8, 2023 · 10 comments

Comments

@LostKobrakai
Copy link
Contributor

Steps to Reproduce

Use runtime.exs to customize the port used for the callback url. E.g. providers: [name: {Strategy, [callback_port: 443]}]

Expected Result

Port to be applied.

Actual Result

Port is not used, because strategy config is compiled into the plug.

@yordis
Copy link
Member

yordis commented Jan 8, 2023

Could this be due to the phoenix plug compilation, by any chance? https://hexdocs.pm/plug/Plug.Builder.html#module-options the init_mode: :compile

It happened to me before outside Ueberatuh, but still, just checking the boxes.

@LostKobrakai
Copy link
Contributor Author

It's configurable, yes, but having the return value for init/1 compiled into any module plug is the default for production use and not a bug.

@yordis
Copy link
Member

yordis commented Jan 8, 2023

I am not sure what you mean precisely.

I do remember that if some plugs want to read things from the environments and rely on runtime.ex then they will need to move the look up to the call/2 callback

@Hajto
Copy link
Contributor

Hajto commented Nov 24, 2023

Whats the status on this one?

@Hajto
Copy link
Contributor

Hajto commented Nov 24, 2023

So I guess the issue would come down to the fact that Providers are initialized during compilation time?

@Hajto
Copy link
Contributor

Hajto commented Nov 24, 2023

After talking with @LostKobrakai on Slack we determined that this boils down to not being able to set any option at runtime due to Plugs being pre-initialized. Thus this makes this related to #170

@yordis
Copy link
Member

yordis commented Nov 24, 2023

My general take, it is frustrating that such behavior is controlled by Plug at the app-level.

The primary question here is, what Plug want people to use init/1 callback for?

We use init to setup up the options. But isn't until a given environment with a given flag come across that we discover that init isn't being called per se at runtime.

🤷🏻 🤷🏻 🤷🏻 🤷🏻 No clue, I think it is worth to bring the conversation to Plug and define some anti-patterns for the community, this is not the first time that it happens to me personally.

I would say, move things to the call/2 callback for now.

@LostKobrakai
Copy link
Contributor Author

Note that init/1 may be called during compilation and as such it must not return pids, ports or values that are specific to the runtime.

Plug init/1 has been documented to likely be executed at compile time since the first version existing on hexdocs. This is very much part of the expectation of how plugs are to be implemented.

The primary question here is, what Plug want people to use init/1 callback for?

It is there to validate and possibly restructure the plug opts passed as input to init/1. Those opts commonly come from the second parameter of the plug/2 macro, where they're also compile time known.

The issue here is that Ueberauth also uses that callback to do the side effect of looking into the application environment.

@Hajto
Copy link
Contributor

Hajto commented Nov 24, 2023

So the technical problem here is that the code we want needs to be executed only once, lazily before first call. Ideally we would like to not have to compute this value every time plug is called. The computation should be very light and only passing but maybe shoving this into ets for cache would be an option?

There is also an option to move this computation to the runtime.exs file, but that smells like an antipattern. Another option would be to maybe add that into the startup_phase, so its precomputed and then stored in something like ETS or dynamically loaded modules. But that also smells.

Maybe first iteration to call the init in the call as previous mentioned? Is there a possibility of this breaking existing code? Should there be an explicit switch to enable this in new iterations of the providers?

@yordis
Copy link
Member

yordis commented Nov 24, 2023

@Hajto keep it simple, like Joe said: make it work, make it beautiful and if you really really need to, make it fast.

Moving the opts to call/2 should fix the issue.

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

No branches or pull requests

3 participants