Page MenuHomePhabricator

[lib] Use httpMessageUserInfosHandler
ClosedPublic

Authored by inka on May 16 2024, 7:03 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Dec 20, 2:51 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Mon, Dec 16, 5:49 PM
Unknown Object (File)
Nov 9 2024, 1:44 AM
Subscribers

Details

Summary

issue: ENG-7821
When I tried using endpointValidators in callSingleKeyserverEndpoint it created import cycles which are hard to fix. An explenation can be found here.
The bottom line is that I cannot import lib/types/validators/endpoint-validators.js from lib/keyserver-conn/call-single-keyserver-endpoint.js. So my workaroud is for lib/keyserver-conn/call-single-keyserver-endpoint.js to expose a function that lets some other place in the code insert the handler to it.

Test Plan

Tested that both web and native apps can be run and no errors are thrown. Tested that the handler correctly extracts user ids from http messages.

Diff Detail

Repository
rCOMM Comm
Lint
No Lint Coverage
Unit
No Test Coverage

Event Timeline

inka requested review of this revision.May 16 2024, 7:19 AM

Is this really the only way to do it? I really don't like this solution, and it feels like something better must be possible.

I don't have time to look at your code directly, but I think it would be good if the reviewers here ran yarn arcpatch and tried to find an alternate solution.

@inka, can you please share the exact path of the import cycle that you are facing? Eg. file1 -> file2 -> file3 -> file1

In the past, when we've faced import cycle issues, we've worked directly to resolve them instead of hacking around them.

lib/keyserver-conn/call-single-keyserver-endpoint.js
81–86 ↗(On Diff #40286)

If this approach is absolutely necessary, we should be doing it in a separate file

Part of the thing that contributes to import cycle issues is when we're doing too much in a single file

web/root.js
42 ↗(On Diff #40286)

Why do we need to register it separately on web and native? Can we import a shared file in lib that will just do the registration in a shared way?

ashoat requested changes to this revision.May 16 2024, 11:59 AM
This revision now requires changes to proceed.May 16 2024, 11:59 AM

Is this really the only way to do it? I really don't like this solution, and it feels like something better must be possible.

I also dislike this solution, but I was unable to find anything I would consider better

@inka, can you please share the exact path of the import cycle that you are facing? Eg. file1 -> file2 -> file3 -> file1

The thing is that this is more than one import cycle. An example is:
lib/utils/reducers-utils.test.js fails with

cpp
      38 |
      39 | function tShape<T>(spec: TStructProps<T>): TInterface<T> {
    > 40 |   return t.interface(spec, { strict: true });
         |            ^
      41 | }
      42 |
      43 | export type TRegex = TRefinement<string>;

      at Function.fail (../node_modules/tcomb/lib/fail.js:2:9)
      at assert (../node_modules/tcomb/lib/assert.js:14:12)
      at Function.inter (../node_modules/tcomb/lib/interface.js:38:5)
      at interface (utils/validation-utils.js:40:12)
      at Object.<anonymous> (shared/updates/join-thread-spec.js:172:24)
      at Object.require (shared/updates/update-specs.js:6:1)
      at Object.require (types/update-types.js:19:1)
      at Object.require (types/validators/entry-validators.js:20:1)
      at Object.require (types/validators/endpoint-validators.js:5:1)
      at Object.require (handlers/http-message-user-infos-handler.js:9:1)
      at Object.require (keyserver-conn/call-single-keyserver-endpoint.js:11:1)
      at Object.require (keyserver-conn/call-keyserver-endpoint-provider.react.js:12:1)
      at Object.require (keyserver-conn/keyserver-call.js:6:1)
      at Object.require (actions/thread-actions.js:7:1)
      at Object.require (shared/messages/text-message-spec.js:13:1)
      at Object.require (shared/messages/message-specs.js:21:1)
      at Object.require (shared/message-utils.js:11:1)
      at Object.require (selectors/thread-selectors.js:28:1)
      at Object.require (shared/avatar-utils.js:11:1)
      at Object.require (shared/thread-utils.js:10:1)
      at Object.require (permissions/special-roles.js:6:1)
      at Object.require (permissions/minimally-encoded-raw-thread-info-validators.js:9:1)
      at Object.require (types/request-types.js:30:1)
      at Object.require (types/socket-types.js:32:1)

because lib/shared/updates/join-thread-spec.js needs ThreadJoinUpdateInfo defined in lib/types/update-types.js , which is already on the stack. It is already on the stack, because it defines serverUpdateInfoValidator which requires updateSpecs which needs joinThreadSpec. serverUpdateInfoValidator cannot be easily moved out of the file, because it depends on many things in it, so it would have to import it anyway.

ThreadJoinUpdateInfo can be moved out of lib/types/update-types.js. But then the test still fails, because lib/shared/updates/update-thread-spec.js needs ThreadUpdateInfo defined in lib/types/update-types.js. If I fix that, the problem becomes that lib/shared/updates/update-thread-spec.js needs mixedRawThreadInfoValidator defined in lib/permissions/minimally-encoded-raw-thread-info-validators.js which is already on the stack. And so on.

because lib/shared/updates/join-thread-spec.js needs ThreadJoinUpdateInfo defined in lib/types/update-types.js , which is already on the stack

That doesn't sound right to me... I don't think Flow types contribute to import cycles. Are you sure that it's not some other non-type import from that file?

I checked this out locally to investigate a little bit on my flight. I ran yarn arcpatch D12073 from master, and then simplified this diff to be a direct import. Several tests started failing; I started my investigation with cd lib && yarn test permissions/minimally-encoded-thread-permissions.test.js.

I found the following pattern in the failure callstack:

at interface (utils/validation-utils.js:40:12)
at Object.<anonymous> (shared/updates/join-thread-spec.js:172:24)
at Object.require (shared/updates/update-specs.js:6:1)
at Object.require (types/update-types.js:19:1)
at Object.require (types/validators/entry-validators.js:20:1)
at Object.require (types/validators/endpoint-validators.js:5:1)
at Object.require (handlers/http-message-user-infos-handler.js:9:1)
at Object.require (keyserver-conn/call-single-keyserver-endpoint.js:10:1)
at Object.require (keyserver-conn/call-keyserver-endpoint-provider.react.js:12:1)
at Object.require (keyserver-conn/keyserver-call.js:6:1)
at Object.require (actions/thread-actions.js:7:1)
at Object.require (shared/messages/text-message-spec.js:13:1)
at Object.require (shared/messages/message-specs.js:21:1)
at Object.require (shared/message-utils.js:11:1)
at Object.require (selectors/thread-selectors.js:28:1)
at Object.require (shared/avatar-utils.js:11:1)
at Object.require (shared/thread-utils.js:10:1)
at Object.require (permissions/special-roles.js:6:1)
at Object.require (permissions/minimally-encoded-raw-thread-info-validators.js:9:1)
at Object.require (permissions/minimally-encoded-thread-permissions.test.js:3:1)

I spent some time investigating different ways to address it by extracting functions to separate files. Ultimately I figured out a simple solution to the issue, which was to extract combineTruncationStatuses to a separate file. This stops the import cycle by breaking the relationship between the message and update specs.

In the process I extracted several other functions to separate files. I'll put diffs up for those too, since they are probably good things that may avoid import cycles in the future.

For the context, this investigation took me <1 hr. I think there are some strategies to handling import cycles that might not be non-obvious to @inka and others on the team; I'd suggest pairing with me in the future to help resolve these, and learn the skills necessary to resolve them on your own.

Update after fixing import cycles

ashoat retitled this revision from [lib][web][native] Use httpMessageUserInfosHandler to [lib] Use httpMessageUserInfosHandler.
This revision is now accepted and ready to land.May 19 2024, 6:08 PM

Thank you so much for fixing this!

This revision was automatically updated to reflect the committed changes.