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

Reply via email to