Closed gomoripeti closed 3 years ago
3rd possible options would be split.
Let's call packages as following - xprof_core
(matching, throttling, tracing etc.), xprof_api
- which is cowboy 2.x
wrapper, xprof_legacy_api
- which is cowboy 1.x
wrapper and xprof_front_end
- which is UI package (with support for both REST APIs).
Then we can publish two packages on hex.pm
:
xprof = xprof_core + xprof_api + xprof_front_end
- for cobwoy 2.x
.xprof_legacy = xprof_core + xprof_legacy_api + xprof_front_end
- for cowboy 1.x
.Benefits:
cowboy
branches we can fix API independently.Drawbacks:
xprof_core
and xprof_front_end
needs to be compatible with all requirements that are set for xprof_legacy
(e.g. support for old Erlang versions - no maps, no fancy stuff added in later VM).xprof_front_end
possibly will need to support 2 different APIs (e.g. v1
and v2
of REST API, or REST API and websockets API).good suggestion
xprof_front_end
xprof_core
needs to be compatible with old Erlang versions anyway so this is no different in any solutionI am a bit scared of introducing so many hex packages and OTP applications (even for a javascript-only component) but I should get over this :) . Maybe we could generate multiple hex packages (xprof_api
/xprof_legacy_api
) from the same OTP application and code base. (These are basically 1 module apps)
I wonder if there is any existing example in the hex world for such fine-grained packaging?
@gomoripeti Yup, it is possible e.g. phoenix
is organized in such way - https://hex.pm/packages/phoenix - phoenix_pubsub
is there by default, also there is phoenix_html
, phoenix_ecto
in your generated application and so on. I wouldn't name that fine-grained, but it is really close to what we want to achieve here.
just a note that if we have xprof_gui
(depending on cowboy 2.0.0) and xprof_legacy_gui
(depending on cowboy 1.1.2) in the same repo/umbrella project, rebar3 will only fetch one of the cowboy versions. (Obviously, to avoid version conflict)
===> Skipping cowboy (from {pkg,<<"cowboy">>,<<"2.0.0">>,
<<"A3B680BCC1156C6FBCB398CC56ADC35177037012D7DC28D8F7E7926D6C243561">>}) as an app of the same name has already been fetched
scetching up deps hell: repo1 (compiles with any Erlang version)
apps/xprof_legacy
ββ apps/xprof_core
ββ apps/xprof_legacy_gui (includes js and common rest module)
ββ cowboy 1.1.2 (hex pkg)
repo2 (Erlang 19+ only):
apps/xprof
ββ xprof_core (hex pkg)
ββ apps/xprof_gui (overrides cowboy version)
ββ cowboy 2.0.0 (hex pkg)
ββ xprof_legacy_gui (hex pkg)
question of naming and what should be the default
naming
_legacy
suffix for old stuff_c2
or _ng
(or you name it) suffix for new stuff(which cowboy version and hence which gui variant to use)
So it seems that cowboy 2.x is a special case, so the default should be the old one. On the other hand it's a good idea to have the new thing as default (in general; forward looking) as later other, new features could come also requiring eg. OTP 19+ (most notably the tracer NIF)
I'd vote for new stuff as a default. I know that will require more work for the older VMs, but that's the deal with supporting and using older stuff - if we're aiming into bigger adoption, the new should be our default.
I am also for keeping new as default and hopefully dropping legacy stuff after some time.
packaging and scenarios (maybe we don't want to support all of them)
raw
and rsync
providers, the solution "OS env var to choose cowboy version" #124 should work in this case
Issues
{cowboy, "~> 2.0.0 ir 1.1.2"}
in rebar.config cause crash like
===> Uncaught error: {badmatch,[<<"2.0.0">>,<<"or">>,<<"1.1.2">>]}
===> Stack trace to the error location:
[{rebar_app_utils,update_source,3,
[{file,"/Users/peter/git/rebar3/_build/default/lib/rebar/src/rebar_app_utils.erl"},
{line,259}]},
multiple version in hex package dependency causes the dependency to be simply skipped
===> [xprof_gui:2.0.0-prealpha.2], Bad dependency version for cowboy: 1.1.2 or ~> 2.0.
...
ββ xprof_guiβ2.0.0-prealpha.2 (hex package)
ββ jsoneβ1.3.1 (hex package)
Why would we support cowboy 1.x
Handling cowboy dependency
{cowboy, "~> 1.1.2 or ~> 2.0"}
then we need to add also amix.exs
to xprofCompiling
platform_define
in xprof'srebar.config
XPROF_COWBOY_1
to enforce cowboy 1.x usage otherwise cowboy 2.x will be used (at compile time!)rebar.config.script
can adjustdeps
based on this (as well as unneeded code can be skipped with ifdef)Runtime
xprof_gui_app
can detect at runtime cowboy version and use the appropriate cowboy API and handler module to start cowboy This is automatic and coolTo sum up there are probably two options
XPROF_COWBOY_1
to enforce version at compile timerebar.config.script
+ ifdefs in codexprof_gui_app
detects verison at runtime...and probably a third, simplest one I did not think of.
Sample WIP code for 1. can be seen here: xprof_gui_cowboy_handler.erl, xprof_gui_app.erl