Coder Social home page Coder Social logo

component's People

Contributors

axelson avatar iaddict avatar pragdave avatar serbort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

component's Issues

forbidden word

You used the word "application" twice in the README! ;-)
Sorry, I just finished watching your EMPEX video.

Missing example?

HI Dave,

Apologies for stating the obvious but at the bottom of the readme you have

MISSING: event counter

and the example is missing.

Usage Guidance

I'm a little concerned that this library to some extent, but more particularly the associated blog post could lead to Elixir new-comers thinking that software design in Elixir is always centered on the concept of user-developed servers, and that concepts such as encapsulation and separation of concerns dictate the usage of servers in ordinary application or business logic that wouldn't otherwise need its own concurrency mechanism.

This already happens - it is not hard to find examples in the wild where people use GenServer for what could be done without concurrency at all, or much more simply with Task.async.

Would it make sense to have some guidance on when a server is needed to begin with? For example, a web request in a framework such as Phoenix should almost never make a synchronous call to a GenServer, as this would single-thread all requests making that call and incur overhead in copying messages.

how do you name components e.g. using via tuples or atom names?

I understand for global components that you don't give names, but how does that work across nodes e.g. i could use syn/global/horde/swarm and have multiple nodes running my program. In my current case i use syn (very nice it is too) and register the genservers with via tuples, but it is not clear from the readme how naming servers with atoms or via tuples works?

Apologies for the question if its obvious!

API design

This looks really interesting!

I am an Elixir noob who wrote his first GenServer last weekend, so this feedback may be very naive and stupid; please ignore it if so.

Although the API is very much simpler and more streamlined than the traditional GenServer, it still has a few moving parts and I wonder if they're totally necessary. From my reading of the readme, it sounds like there are exactly 3 things that you might want to do when you interact with a component:

  1. Update the state of the component
  2. Get a reply from the component
  3. Update the state and get a reply

With the current API, there are two things that the user needs to do to achieve these results:

  1. Choose between one_way and two_way (2 options)
  2. Choose whether to use set_state, set_state_and_return, or neither (3 options)

That gives you 6 possible combinations of things you could write, but only 4 of them will do what you want.

two_way -> OK (replies without updating the state)
two_way + set_state -> OK (updates the state and replies with the new state)
two_way + set_state_and_return -> OK (updates the state and replies with something else)
one_way -> OK (updates the state without replying)
one_way + set_state -> ?
one_way + set_state_and_return -> ?

Would it be possible/desirable to have an API that was more like this?

defmodule KV do

  use Component.Strategy.Dynamic,
      state_name:    :kv_store,
      initial_state: %{}

  handle add(kv_store, key, value) do
    %{state: Map.put(kv_store, key, value)}
  end

  handle get(kv_store, key) do
    %{reply: Map.get(kv_store, key)}
  end

  handle merge_and_tell_me_the_new_value(kv_store, key, new_value) do
    new_kv_store = Map.update(kv_store, key, new_value, fn old_value -> old_value + new_value end)
    merged_value = Map.get(new_kv_store, key)
    %{
      state: new_kv_store,
      reply: merged_value
    }
  end
end

That way, the user doesn't have to think about which type of function they're writing - they just need to specify what they want to get out of it - a new state, a reply, or both.

How does the component handle supervision trees

Very well written and interesting post!

With components how do you handle supervision trees if all the components (and hence supervision trees) are independent of each other?

I would be interested in seeing an example app (beyond trivial!) that handles genserver messages eg handle_info, terminate etc.

I look forward to see what conversation this library generates!

one_way should return self() pid, not :ok

In your blog post leading up to some of these ideas, you use a cool trick.

When the original logic code decided it needed to be wrapped in a server, you made sure the server setter's returned pid, so you were still returning the new state as usual in functional language

(although now the state was "opaquely" represented by a pid, instead of the naked %{} or whatever other internal data structure)

As you mentioned, this kept the original api the exact same. It was beautiful! If you wrote tests or had other modules already using the "just logic" code, you didn't have to change anything. You could even keep using pipelines since the "state" was passed back at each step

  def new() do
    { :ok, names } = GenServer.start_link(Kv.Server, %{})
    names
  end
  
  def lookup(names, name) do
    GenServer.call(names, {:lookup, name})
  end
  
  def store(names, name, value) do
    GenServer.cast(names, { :store, name, value })
    names
  end

Anything that used to do:

kv =
  Kv.new()
  |> Kv.store("Cat", "meow")

assert Kv.lookup(kv, "Cat") == "meow

Still works. Pipelines don't break. The internal api changing from pure logic to being wrapped in a genserver didn't show to outsiders

Could this library's "one_way" maintain that idea by any chance and return the pid instead of :ok

Need to handle default parameters

Right now, a one_way or two_way declaration that contains default parameters blows up during compilation because the default is also used in the GenServer tuple.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.