Improve error message.
Add characterization tests for existing behavior regarding ZeroMQ socket
creation by RubyDSL.
Connect component inputs before outputs.

Aiming toward using ZeroMQ in-proc sockets for in-shard connections.
Unlike other ZeroMQ sockets, inproc sockets require 'bind' to be called
strictly before 'connect', so iterating and starting ports by component
is not going to work. We need to get all the input ports binding before
we get the output ports connecting.
Use inproc ZeroMQ sockets for in-shard comms.

This has the happy benefit that for connections within a shard, there's
no longer any communications between shards. That is, a message flowing
A->B->C (where a shard contains A, B, and C) will always remain on that
shard, not possibly move to another shard because there are IPCs between
components.

We don't need to namespace the inproc sockets with anything other than
connection UUID, because there will only be one copy of any connection
within any given shard, and each shard will gets own copy of the inproc
socket.
Bind one-to-many connections on the cardinality-1 side.

Fan-in (many-to-one) worked already, because the consumer (input port)
`bind`ed the socket and all the producers (output ports) `connect`ed.

Fan-out (one-to-many) would only route to one consumer, because all the
consumers tried to `bind` the same socket, and all of them got clobbered
and the last one to `bind` was the only one to receive messages. We need
to run the `bind`/`connect` pair the other way for fan-out.

Many-to-many will require a broker solution using zmq_proxy.