I've been thinking about the sending and receiving part. Tao, I'm not
sure how you want to handle this. I know you want to do something like:
circuit.send(msg)
but this seems to make things confusing because you send from the
circuit but then receive from the dispatcher:
dispatcher.receive() (which will call the circuit's handle event message)
So, with sending and receiving in different areas, I think it makes the
api harder. I'm not sure the solution, but it seems they should go in
the same place.
Christian Scholz wrote:
Timothy Loughlin (Locklainn Linden) schrieb:
First, I won't be around for Tues and Wed. I have to take care of
some training for grad school. This means you guys have 3 days to
review this stuff and make a decision! w00t!
Here is the design proposal for the message system refactoring. After
writing this up and looking at my branch code and Tao's, it seems
what we have in our branches is the only good solution thus far.
Also, we have essentially the same design, just with some different
naming. They perform the same functions in almost the same way.
*Similarities:
*what Tao calls EndPoint I call NetUDPClient (which is ZCAified so it
can be swapped)
what Tao calls UDPDispatcher I call MessageSystem (or UDPConnection
in my branch)
As I mentioned somewhere I am actually not sure if the way I initially
did the TCP part works that well with e.g. twisted. So maybe the
network layer at all wasn't such a good idea as it assumes that this
is the lowest layer and e.g. circuits use it.
I'd rather think that the networking layer is in the application and
it mainly passes data in and out to be handled. Also I wonder what
possibilities there are right now to exchange the NetUDPClient. It
cannot be replaced right now to use twisted. The same would be true
for the HTTPClient. (with right now I mean trunk).
So having it like discussed in the earlier mail might work better
then. Once this is refactored I would then look into HTTP and maybe
build some example twisted app which does presence or so.
*Differences:
*Tao's sending and receiving functionality is split apart. All
receiving is through the UDPDispatcher, which then dispatches to a
circuit to handle (exactly the same as Lock's). However, sending is
different in that in Tao's branch you send a message by having direct
access to a circuit. The circuit is hard-wired to a single remote
host, and so you don't pass in the destination when sending. With
Lock's, every time you send a message, you tell it which destination
it will go to.
I want to note that this wasn't finished and I was far from being
happy with it. My brain was just at it's recursion depth limit ;-)
As for the address thing you are right. But I put in the endpoint you
give to the connection constructor (which is the circuit) which can be
a shared socket (or wraps it rather). But you are right that it didn't
know the address which was a problem I found hard to solve back then.
(at least so that the API is the same for all cases)
For example, here is the difference in sending and receiving (putting
the terms into Lock's terms to show the similarity and differences
easily)
*
Receiving:
*Both:
MessageSystem:
receive() (also called handle() ):
size = 10000
data, address = self.udp_client.recvfrom(size)
if address not in self.circuit_list:
error
circuit = find_circuit(address)
circuit.process(data)
NOTES:
This call, receive(), can be wrapped in any way the user wants. It
can be threaded, used as a callback, non-blocking IO, whatever.
Well, it can't be a callback as you cannot pass data in you want to be
handled. In twisted you get some data from a transport and you'd need
to pass it to receive. The receivefrom is already done (or rather done
in a non-blocking fashion).
The difference between Tao's code and Lock's for receive is how a
circuit gets added to the Message System's circuit list. In Tao's,
one must manually call message_system.add_circuit(circuit). In
Lock's a new circuit is created when the user sends to a new
address/port or when it gets a message (receives) from a new
address/port. The user doesn't use connection directly, then, but
they are simply used as ways to keep track of packet acks. Note that
this is the same in both as well, because even in Tao's code the
circuit delegates sending and receiving to some udp client (called
EndPoint).
I personally would prefer some wrapping like this:
Region(Circuit())
So the region knows it's connection and can instantiate it when it's
created itself (e.g. after place_avatar). This way each object knows
directly the one it's using.
The problem is of course the shared socket or some twisted code. This
is why I think that the networking layer actually needs to move up as
it seems to be the main driving force of the whole application.
*Sending:*
Tao:
message_system= MessageSystem()
conn = Connection(message_system, (address, port))
msg = Message(...)
conn.send(msg)
Lock:
message_system= MessageSystem ()
msg = Message(...)
message_system.send(msg, (address, port))
NOTES:
The differences lie in the fact that in Tao's branch you create a
connection explicitly, tie the connection with an address/port, and
send the message through the connection. In Lock's way, you send a
message to the target address/port all the time, never having access
to the circuit itself. The message system determines if the
combination is new, if so, creates a new circuit for it automatically.
*Decision:*
My vote is that we keep the design in my branch because it is mostly
finished and functional (with packet flags and all that already
working). I vote this because our designs are almost identical, with
only a naming difference. So, let's come up with the names for these
things and we will have our refactor design.
I would vote for slightly moving things from the message system to the
circuit so that you can also use it without the message system. Like
adding flags and such. This wouldn't change anything to the outside API.
For the real differences, we must decide whether or not the Message
System does the sending, or if the circuit does the sending (which
delegates to some udp client). My thoughts are that because in Tao's
branch the circuit is doing the sending and the message system doing
the receiving, we need a single udp_client, or socket at the lowest
level, and so this will be shared among the circuit and the message
system (with message system having circuits as well). We then have to
pass this socket (or EndPoint) to both the MessageSystem and the
Circuit, which makes it 1 or 3 steps more to set up sending. With
Lock's design, the EndPoint, socket, or udp_client is automatically
the same for sending and receiving.
But I am not sure it works with twisted. You need to pass something to
use for sending. In twisted you don't use sockets directly. That was
the reason for my endpoint. It's not only about single or shared socket.
So the endpoint needs to come from the application and needs to be
passed.
Note that the socket issue, whether or not a single socket is used
per connection or if a single socket is used for all connections, is
exactly the same for both designs. In both designs you have to create
a new MessageSystem, or UDPDispatcher (which also needs a new
EndPoint to be created as well).
Also note that it isn't currently possible to have both designs (one
that has access to connections and one that doesn't). This is because
in my design the connections are under the hood of the message
system.We COULD, however, add this functionality to the message
system, which means having the message system be a way to create
circuits:
message_system = MessageSystem()
conn1 = message_system.create_circuit(address, port)
msg = Message(...)
conn1.send(msg)
I think it is possible to give the user the possibility to not use the
message system but something else. Then we could keep most of the
stuff which is there and only would need to move things slightly.
I guess we should discuss this tomorrow :)
-- Christian
_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp
_______________________________________________
Click here to unsubscribe or manage your list subscription:
https://lists.secondlife.com/cgi-bin/mailman/listinfo/pyogp