The issue of having to use undocumented functions is, unfortunately, not unusual in Erlang. OTP has accumulated a bunch of functions over the years and there are several functions in the standard library that are not exposed and yet are used.
For example: lists:zf/2 eventually became lists:filtermap/2, but zf/2 is still exposed, although undocumented. Same with lists:rmerge/2 and lists:rmerge3/3—exposed but undocumented.
With regards to using os:env/0, if you know the data won’t change, it’s recommended to pull it into your application environment (and use application:get_env/2 or similar) since that’s backed by an ETS table. Another option is to use persistent_term if it’s available in your OTP version, since it will allow you to read configuration data without copying any memory.
I can see this causing trouble in certain environments. And article mentioned 90 env variables is even not that many. For example in a quite busy Kubernetes namespace I right now have pods that have not disabled enableServiceLinks in PodSpec and have ~700 env variables set (each Service gets bunch of env vars automatically set for every exposed port).
This is exactly what happened to the application I mentioned in the post. Prior to migrating to Kubernetes I think this app was run in an environment with only a couple dozen variables. And after the move to Kubernetes I think we had around ~1200 set.
This is great. On the one hand, it’s kind of silly that this was a problem. On the other hand, I 100% believe that Elixir has existed for almost a decade without someone serious writing performance-sensitive code that called System.get_env/0 dozens of times per request. Welcome to computers!
The issue of having to use undocumented functions is, unfortunately, not unusual in Erlang. OTP has accumulated a bunch of functions over the years and there are several functions in the standard library that are not exposed and yet are used.
For example:
lists:zf/2
eventually becamelists:filtermap/2
, butzf/2
is still exposed, although undocumented. Same withlists:rmerge/2
andlists:rmerge3/3
—exposed but undocumented.With regards to using
os:env/0
, if you know the data won’t change, it’s recommended to pull it into your application environment (and useapplication:get_env/2
or similar) since that’s backed by an ETS table. Another option is to usepersistent_term
if it’s available in your OTP version, since it will allow you to read configuration data without copying any memory.I can see this causing trouble in certain environments. And article mentioned 90 env variables is even not that many. For example in a quite busy Kubernetes namespace I right now have pods that have not disabled
enableServiceLinks
in PodSpec and have ~700 env variables set (each Service gets bunch of env vars automatically set for every exposed port).This is exactly what happened to the application I mentioned in the post. Prior to migrating to Kubernetes I think this app was run in an environment with only a couple dozen variables. And after the move to Kubernetes I think we had around ~1200 set.
I have been unamused with Elixir apps on Kubernetes and Docker, but here we are. :(
This is great. On the one hand, it’s kind of silly that this was a problem. On the other hand, I 100% believe that Elixir has existed for almost a decade without someone serious writing performance-sensitive code that called
System.get_env/0
dozens of times per request. Welcome to computers!I am surprised they don’t use pipelines in the stdlib.
Not everywhere it is possible and if you have only single step pipeline then it is preferred to do just regular call instead of pipeline macro.