Yup. Although, to be pedantic, the offer/ack is often unicast. Here's the relevant bit from the RFC.
> If the 'giaddr' field in a DHCP message from a client is non-zero,
the server sends any return messages to the 'DHCP server' port on the
BOOTP relay agent whose address appears in 'giaddr'. If the 'giaddr'
field is zero and the 'ciaddr' field is nonzero, then the server
unicasts DHCPOFFER and DHCPACK messages to the address in 'ciaddr'.
If 'giaddr' is zero and 'ciaddr' is zero, and the broadcast bit is
set, then the server broadcasts DHCPOFFER and DHCPACK messages to
0xffffffff. If the broadcast bit is not set and 'giaddr' is zero and
'ciaddr' is zero, then the server unicasts DHCPOFFER and DHCPACK
messages to the client's hardware address and 'yiaddr' address. In
all cases, when 'giaddr' is zero, the server broadcasts any DHCPNAK
messages to 0xffffffff.
Sure async/await makes your casde more complicated .
That reason why, I prefer use Go for I/O wait application because I don't need to manage this Go doesn't it fore me.
My code still readable and simple.
> While the story behind the coinage of LGTM remains murky at best, the earliest known use and explanation of the acronym can be traced to a feature summary of Google Mondrian, a peer-review software application for programmers, posted by Niall Kennedy[3] on November 30th, 2006.
The claims regarding JVM bloat are largely exaggerated, especially now that the JVM introduced modules. However, if it's not your thing it's worth noting that ClojureScript happily runs on Node. Here's an example of how easy it is to get up and running with https://github.com/yogthos/mastodon-bot
I'm working on my first Clojure project and find JVM to be painful (it starts very slowly and eats lots of RAM). I'd appreciate any tips on making JVM non-bloated.
If start time and memory usage is important to you, go with ClojureScript on Node instead.
If you do stick with the JVM, it tends to trade memory for speed, unless you tune it otherwise. For startup speed, start it once, connect a REPL, and keep it running. A started REPL on a JVM instance can be flushed very quickly when you need a blank slate.
Don't know about bloat fixes, but what does your workflow look like that JVM starts are annoying? My Emacs CIDER REPL comes up in 4 seconds (MB Pro 16G) and it's often many hours (even days sometimes) between restarts.
But yes, slow starts are annoying if you're starting a JVM frequently. Can you change your workflow so that's not needed? Check out Component, Mount or Integrant.
We're using Integrant already so yes, I can mostly work in a REPL without restarting. But the restarts are more like 15 seconds. I'll have to measure and see what's so slow. My rdev platform is Cursive on a 16G MBP.
And while I'm commenting, yes, we have a reason to run on JVM (a lot of legacy Java code we probably want to interface with later on). So thanks to other commenters for suggesting Node.js and Common Lisp, but not possible. :)
Don't underestimate Erlang's capacity for eating-up all the RAM on a machine in very quick time. Those lightweight processes start to add up if left unchecked. At least the JVM establishes an upper limit on memory use from the outset.
Discover: first request broacasted by client in order to get lease (@ip and others configurations)
Offer: response bradcasted by server with the lease (@ip and others configurations)
Request: broacasted by the client in order to confirm the usage of this lease(from this server, others server can release other lease)
Ack: ack from server