25 Matching Annotations
  1. Oct 2020
    1. HTTP CLIENT SERVICE START/STOP An HTTP client can be configured to start when starting the Inets application or started dynamically in runtime by calling the Inets application API inets:start(httpc, ServiceConfig) or inets:start(httpc, ServiceConfig, How), see inets(3). The configuration options are as follows: {profile, profile()} Name of the profile, see DATA TYPES. This option is mandatory. {data_dir, path()} Directory where the profile can save persistent data. If omitted, all cookies are treated as session cookies. The client can be stopped using inets:stop(httpc, Pid) or inets:stop(httpc, Profile).

      inets:start() will automatically start the httpc service also!

      https://stackoverflow.com/a/64212985/1498178

    2. profile() = atom()

      This should be profile() = default | atom() because the httpc service is automatically started with the default profile (called default) when inets is started.

      See also How to get more information about error when starting Inets httpd?

    1. The HTTP client default profile is started when the Inets application is started and is then available to all processes on that Erlang node.
  2. Sep 2020
    1. To me, abandoning all these live upgrades to have only k8s is like someone is asking me to just get rid of all error and exceptions handling and reboot the computer each time a small thing goes wrong.

      the Function-as-a-Service offering often have multiple fine-grained updateable code modules (functions) running within the same vm, which comes pretty close to the Erlang model.

      then add service mesh, which in some cases can do automatic retry at the network layer, and you start to recoup some of the supervisor tree advantages a little more.

      really fun article though, talking about the digital matter that is code & how we handle it. great reminder that there's much to explore. and some really great works we could be looking to.

  3. Jul 2020
    1. The keys will be copied to the heap for the process calling get/0, but the values will not.

      What does this mean?

    1. If the run-time dependencies were shared across all applications depending on the same rebar.config file,

      This sentence is straightforward but I only understood it just now.

      rebar.config can specify the dependencies of all the applications in the umbrella project, but they are not necessarily run-time dependencies. Also, the relx example from the rebar.config above shows how to include an app/lib (in this case, recon) in the final production release, even if it is not a run-time dependency.

      This guide also expands on it a paragraph below:

      The Rebar3 maintainers therefore just decided to keep a clear distinction between the applications that need fetching for the project to build or run (in rebar.config), and the run-time dependencies of each OTP application (in the .app file) which may be part of the default OTP install, and would therefore not be included in rebar.config. Other build tools in the ecosystem let you achieve similar results, but they default to including everything at run-time whereas Rebar3 asks of developers to always be specific in their intent.

    1. mark the workers as permanent or transient, so that if they fail they get restarted

      restart defines when a terminated child process must be restarted.

      • A permanent child process is always restarted.
      • A temporary child process is never restarted (even when the supervisor's restart strategy is rest_for_one or one_for_all and a sibling's death causes the temporary process to be terminated).
      • A transient child process is restarted only if it terminates abnormally, that is, with another exit reason than normal, shutdown, or {shutdown,Term}. https://erlang.org/doc/man/supervisor.html
    1. The most commonly supported tool for this is kerl. Kerl is a wrapper around downloading, compiling, and loading various Erlang/OTP versions on a single system, and will abstract away most annoying operations.
  4. May 2020
    1. In OTP 22 we introduced the new experimental socket API. The idea behind this API is to have a stable intermediary API that can be used to create features that are not part of the higher-level gen_* APIs. We have now come one step further in our plan to replace the inet driver by making it possible to use the gen_tcp API with socket as an optional back-end. To make it easy to test with existing code using gen_tcp a new option {inet_backend, socket | inet} can be used to select the socket implementation instead of the default inet implementation.

      Q1: So inet and socket are competing socket implementations then?

      Q2: inets is higher level abstraction layer on top of inet? (Just as HTTP is higher level than transport protocols.)

      Q3 (corollary of Q1 and Q2): inets could be then rewritten to use socket instead? (And used just like gen_tcp with the inet_backend option?)

    1. Programming languages These will probably expose my ignorance pretty nicely.

      When to use different programming languages (advice from an Amazon employee):

      • Java - enterprise applications
      • C# - Microsoft's spin on Java (useful in the Microsoft's ecosystem)
      • Ruby - when speed is more important then legibility or debugging
      • Python - same as Ruby but also for ML/AI (don't forget to use type hinting to make life a little saner)
      • Go/Rust - fresh web service where latency and performance were more important than community/library support
      • Haskell/Erlang - for very elegant/mathematical functional approach without a lot of business logic
      • Clojure - in situation when you love Lisp (?)
      • Kotlin/Scala - languages compiling to JVM bytecode (preferable over Clojure). Kotlin works with Java and has great IntelliJ support
      • C - classes of applications (operating systems, language design, low-level programming and hardware)
      • C++ - robotics, video games and high frequency trading where the performance gains from no garbage collection make it preferable to Java
      • PHP/Hack - testing server changes without rebuilding. PHP is banned at Amazon due to security reasons, but its successor, Hack, runs a lot of Facebook and Slack's backends
  5. Apr 2020
    1. If we refer to the CAP theorem, Mnesia sits on the CP side, rather than the AP side, meaning that it won't do eventual consistency, will react rather badly to netsplits in some cases, but will give you strong consistency guarantees if you expect the network to be reliable (and you sometimes shouldn't).

      We start out with the TL;DR treatise: The mnesia database is not CP, nor AP. And it cannot be CA, because CA doesn’t make any meaningful sense. In short, it is broken with respect to the CAP theorem. https://medium.com/@jlouis666/mnesia-and-cap-d2673a92850

  6. Mar 2020
  7. Feb 2020
  8. Jan 2020
  9. Nov 2019
  10. Oct 2018
  11. Sep 2018
    1. This is a transcript of a talk given at ElixirDaze and CodeBEAMSF conferences in March of 2018, dealing with supervision trees and with the unexpected.
  12. Dec 2017
    1. If the entire tables are constant over a long time, you could generate them as modules. Nowadays, compile-time constants (even complex ones) are placed in a constant pool associated with the module. So, you could generate something like this: -module(autogen_table). -export([find/1]). find(0) -> {some_struct, "hello", ...}; ... find(99) -> {some_other_struct, <<"hi!">>} find(X) -> throw({not_found, X}). As far as I know, these constants will not be copied to the private heaps of the processes. The generated code will also give you the fastest possible lookup.

      This is a pretty cool trick. So looks like a way to bypass the copying overhead is to make a function that only has constant outputs and doesn't actually compute anything.

    1. To summarize: without queuing mechanism: same Erlang node: 5.3 million messages/min; different Erlang nodes: 700 K messages/min. with queuing mechanism: same Erlang node: 5.3 million messages/min; different Erlang nodes: 2.1 million messages/min. The complete code to run this on your machine is available here. This whole ‘queuing idea’ is still an experiment, and I’d be more than delighted to hear your feedback, to see whether you are getting the same results, you know how to improve the concept or the code, or you have any considerations at all you would like to share.

      I got here from the discord blog on how they optimized their performance and it looks like the trick is to batch messages when sending to remote nodes. Seems kinda obvious though that batching messages would improve performance.

      A trick to keep in the back pocket.

  13. Feb 2017