New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Networking See PR #532 #665

Open
wants to merge 12 commits into
from

Conversation

Projects
None yet
5 participants
@jojolepro
Collaborator

jojolepro commented Apr 24, 2018

See PR #532 for all comments. This is just the same re-opened because bors won't merge the other one.


This change is Reviewable

jojolepro added some commits Feb 1, 2018

Network implementation for amethyst.
-Message-Passing based.
-Connection protocols.
-Mio Poll based to avoid packet loss during overflows.

Early component serialization tests

Tested enum as deserialization vector

Added basic connection management and protocols. Fully implemented only client side in this commit

More connection stuff, and some lifetime errors

Update to DeserializeOwned

Working connection management

Cleaned code + finished the connection stuff

Partial review application

Applied most reviews. Compile error present.

Fixed all reviews to date. Inverted the NetEvent hierarchy.

idk what's going on :P

Progress on send queues

Progress on connection pool

Progress on the connection resource and event queues. Started implementing the bundles

Updated deps

Progress on send and receive pools. Filters progression.

merge

backup

Changed crate structure, finished connection manager, fixed examples. Not ready for review

Removed useless generic bounds

Improved doc. Mostly complete NetIdentity impl

idk how to integrate mio, obviously

early fmt

progress

progress

Integrated mio, still WIP

Cleaning

fmt

Applied @Rhuagh review

Add temp seizure warning

Add part 3 to the pong tutorial in the book.

Add line breaks to chapter 03 of pong tutorial.

Make various improvements to ch3 of pong tutorial.

1. Formatting (backticks around types, and indentation).
2. Clarification for confusing/misleading portions.
3. Caution regarding framerate locking.

Add completed code for chapter 3 of pong tutorial.

Cleanup pong_tutorial_03 example

Move source code out of `src`.
Resolve path same way as other pong examples.
Add missing code snippet for adding system to ApplicationBuilder.

check handle uniqueness after we check if the asset can even be loaded

remove whitespace
@Rhuagh

Rhuagh approved these changes Apr 24, 2018

@Xaeroxe

bors r+

bors bot added a commit that referenced this pull request Apr 24, 2018

Merge #665
665: Networking See PR #532 r=Xaeroxe a=jojolepro

See PR #532 for all comments. This is just the same re-opened because bors won't merge the other one.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/amethyst/amethyst/665)
<!-- Reviewable:end -->


Co-authored-by: jojo <jojolepromain@gmail.com>
Co-authored-by: Joël Lupien (Jojolepro) <jojolepromain@gmail.com>
@bors

This comment has been minimized.

Show comment
Hide comment
Contributor

bors bot commented Apr 24, 2018

@Xaeroxe

This comment has been minimized.

Show comment
Hide comment
@Xaeroxe

Xaeroxe Apr 24, 2018

Member

cache got too big 0_o

bors retry

Member

Xaeroxe commented Apr 24, 2018

cache got too big 0_o

bors retry

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 24, 2018

Collaborator

nice
I guess I won't be doing any big PR anytime soon.

Collaborator

jojolepro commented Apr 24, 2018

nice
I guess I won't be doing any big PR anytime soon.

bors bot added a commit that referenced this pull request Apr 25, 2018

Merge #665
665: Networking See PR #532 r=Xaeroxe a=jojolepro

See PR #532 for all comments. This is just the same re-opened because bors won't merge the other one.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/amethyst/amethyst/665)
<!-- Reviewable:end -->


Co-authored-by: jojo <jojolepromain@gmail.com>
Co-authored-by: Joël Lupien (Jojolepro) <jojolepromain@gmail.com>
@bors

This comment has been minimized.

Show comment
Hide comment
Contributor

bors bot commented Apr 25, 2018

@Xaeroxe

This comment has been minimized.

Show comment
Hide comment
@Xaeroxe

Xaeroxe Apr 25, 2018

Member

bors retry

Member

Xaeroxe commented Apr 25, 2018

bors retry

@omni-viral

omni-viral requested changes Apr 25, 2018 edited

I suggest to use multi-level event handling.

  1. Designated thread does polling mio and sends tasks to thread-pool.
  2. Thread-pool handles network events.
    It may precompute some data, collapse multiple network events into single one and so on.
  3. Events that affect World enqueued into queue which is processed by System.
    Network events and input events can be handled by that system together as there are similarities. Like character controlling events from players local and remote.

And I'd want real examples. Like sending pong state over the network.

Also it may be better to use more abstract data sources than sockets.
There are crates for async IO which should be useful here.

+ }
+
+ for ev in events.buf.read(self.net_event_reader.as_mut().unwrap()) {
+ if self.is_server {

This comment has been minimized.

@omni-viral

omni-viral Apr 25, 2018

Member

Looks like this system should be split in two.

@omni-viral

omni-viral Apr 25, 2018

Member

Looks like this system should be split in two.

+ /// Notify the clients(including the one being disconnected) that a client has been disconnected from the server.
+ Disconnected {
+ /// The reason of the disconnection.
+ reason: String,

This comment has been minimized.

@omni-viral

omni-viral Apr 25, 2018

Member

Disconnect and other reasons should be an enum of well-known reasons + custom one with String.

@omni-viral

omni-viral Apr 25, 2018

Member

Disconnect and other reasons should be an enum of well-known reasons + custom one with String.

This comment has been minimized.

@jojolepro

jojolepro Apr 25, 2018

Collaborator

true

@jojolepro

jojolepro Apr 25, 2018

Collaborator

true

+ reason: String,
+ },
+ /// A simple text message event.
+ TextMessage {

This comment has been minimized.

@omni-viral

omni-viral Apr 25, 2018

Member

How this one must be interpreted by engine user?

@omni-viral

omni-viral Apr 25, 2018

Member

How this one must be interpreted by engine user?

This comment has been minimized.

@jojolepro

jojolepro Apr 25, 2018

Collaborator

info!("")
Those are arbitrary debugging messages.
For example "Client 1. Time is: 3254, ping is: 6451, client state: Connected".

@jojolepro

jojolepro Apr 25, 2018

Collaborator

info!("")
Those are arbitrary debugging messages.
For example "Client 1. Time is: 3254, ping is: 6451, client state: Connected".

This comment has been minimized.

@omni-viral

omni-viral Apr 25, 2018

Member

I can't see it from variant name though. Neither engine user will do

@omni-viral

omni-viral Apr 25, 2018

Member

I can't see it from variant name though. Neither engine user will do

This comment has been minimized.

@jojolepro

jojolepro Apr 25, 2018

Collaborator

I can rename it DebugTextMessage.

@jojolepro

jojolepro Apr 25, 2018

Collaborator

I can rename it DebugTextMessage.

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 25, 2018

Collaborator

Designated thread does polling mio and sends tasks to thread-pool.

We'll have thread starvation issues, as we have with audio already when the game is under heavy load.

Network events and input events can be handled by that system together as there are similarities. Like character controlling events from players local and remote.

You can do that by simply using a EventChannel<NetEvent> in any system you want.

And I'd want real examples. Like sending pong state over the network.

Me too, but I have to wait for specs 0.11. I also have to rethink how I want the entity ownership to work. Mainly, I need to tag components I want to sync (Marked?) and then find a way to deserialize them on the receiving end without actually having the type. Basically the same problem that I had with NetEvent, but I can't use an enum...

Also it may be better to use more abstract data sources than sockets.

I already talked about it. Recap: Its a planned feature, but it will require a completely separate abstraction PR for it. (I'm planning on doing it in the 3rd one, while this is the first one. The second one will be component/entity sync/creation/destruction/ownerships).

There are crates for async IO which should be useful here.

Except for tokio and a couple of lower level subcrates, I didn't see much that were promising and didn't require a completely separate thread. Since most people are against using futures, the choice is pretty limited.

Collaborator

jojolepro commented Apr 25, 2018

Designated thread does polling mio and sends tasks to thread-pool.

We'll have thread starvation issues, as we have with audio already when the game is under heavy load.

Network events and input events can be handled by that system together as there are similarities. Like character controlling events from players local and remote.

You can do that by simply using a EventChannel<NetEvent> in any system you want.

And I'd want real examples. Like sending pong state over the network.

Me too, but I have to wait for specs 0.11. I also have to rethink how I want the entity ownership to work. Mainly, I need to tag components I want to sync (Marked?) and then find a way to deserialize them on the receiving end without actually having the type. Basically the same problem that I had with NetEvent, but I can't use an enum...

Also it may be better to use more abstract data sources than sockets.

I already talked about it. Recap: Its a planned feature, but it will require a completely separate abstraction PR for it. (I'm planning on doing it in the 3rd one, while this is the first one. The second one will be component/entity sync/creation/destruction/ownerships).

There are crates for async IO which should be useful here.

Except for tokio and a couple of lower level subcrates, I didn't see much that were promising and didn't require a completely separate thread. Since most people are against using futures, the choice is pretty limited.

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 25, 2018

Collaborator

Thanks for the review, btw ;)

Collaborator

jojolepro commented Apr 25, 2018

Thanks for the review, btw ;)

@omni-viral

This comment has been minimized.

Show comment
Hide comment
@omni-viral

omni-viral Apr 25, 2018

Member

We'll have thread starvation issues

I see network polling once in 17ms (60 fps) as starved already. Also. If we will have control over that thread we could ensure it does polling frequently enough. With audio we have no control over playback thread.

You can do that by simply using a EventChannel

Is EventChannel<NetEvent> capable to broadcast all of network events under heavy load?

Since most people are against using futures

I can't understand why people are against futures. We tried to use them wrong and went into troubles. Well. Next time we can try to use them right 😏

Member

omni-viral commented Apr 25, 2018

We'll have thread starvation issues

I see network polling once in 17ms (60 fps) as starved already. Also. If we will have control over that thread we could ensure it does polling frequently enough. With audio we have no control over playback thread.

You can do that by simply using a EventChannel

Is EventChannel<NetEvent> capable to broadcast all of network events under heavy load?

Since most people are against using futures

I can't understand why people are against futures. We tried to use them wrong and went into troubles. Well. Next time we can try to use them right 😏

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 25, 2018

Collaborator

Is EventChannel capable to broadcast all of network events under heavy load?

Yes. I made it run at 10k events per frame.

I can't understand why people are against futures. We tried to use them wrong and went into troubles. Well. Next time we can try to use them right

I like futures, but the problem is that they can complete at any time. Forking the execution thread is easy but merging it back into the main execution loops is much harder. The way to solve it is to use the equivalent of unity's coroutines: You run your future normally, but when it completes, it stores the result in some temporary buffer (locking). Then from the main loop (in the sense that it has to happen during an update() frame) you get that result and call the action that is supposed to happen. This is a limitation inherent to the fact that amethyst is frame-based.

Frame based: It starts with a state, applies a set of instructions on it and ends up with a new step.

Futures are better with completely async systems: You can fork the execution as much as you want because you are not required to have a global end state to compute.

(My scala engine I wrote was a completely async, actor + ecs based. The problem with that is that you cannot have dependency cycles at all. You can't have physics depending on the position that depends on physics that depends on AI.)

I didn't mean to write so much on this lol

Collaborator

jojolepro commented Apr 25, 2018

Is EventChannel capable to broadcast all of network events under heavy load?

Yes. I made it run at 10k events per frame.

I can't understand why people are against futures. We tried to use them wrong and went into troubles. Well. Next time we can try to use them right

I like futures, but the problem is that they can complete at any time. Forking the execution thread is easy but merging it back into the main execution loops is much harder. The way to solve it is to use the equivalent of unity's coroutines: You run your future normally, but when it completes, it stores the result in some temporary buffer (locking). Then from the main loop (in the sense that it has to happen during an update() frame) you get that result and call the action that is supposed to happen. This is a limitation inherent to the fact that amethyst is frame-based.

Frame based: It starts with a state, applies a set of instructions on it and ends up with a new step.

Futures are better with completely async systems: You can fork the execution as much as you want because you are not required to have a global end state to compute.

(My scala engine I wrote was a completely async, actor + ecs based. The problem with that is that you cannot have dependency cycles at all. You can't have physics depending on the position that depends on physics that depends on AI.)

I didn't mean to write so much on this lol

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 25, 2018

Collaborator

Its probably possible to have a separate thread to poll the network socket, but the events will be consumed by the ecs only when the update() loop is there. Might as well just poll the socket during the loop at that point. Mio prevents packet loss slow stepping, from what I have seen.

Collaborator

jojolepro commented Apr 25, 2018

Its probably possible to have a separate thread to poll the network socket, but the events will be consumed by the ecs only when the update() loop is there. Might as well just poll the socket during the loop at that point. Mio prevents packet loss slow stepping, from what I have seen.

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Apr 25, 2018

Collaborator

Its a separate topic, but if someone can come up with an architecture that allow using Futures in a stepping engine without requiring locking buffers (or buffers at all), please open a rfc.

Collaborator

jojolepro commented Apr 25, 2018

Its a separate topic, but if someone can come up with an architecture that allow using Futures in a stepping engine without requiring locking buffers (or buffers at all), please open a rfc.

@jojolepro

This comment has been minimized.

Show comment
Hide comment
@jojolepro

jojolepro Jul 9, 2018

Collaborator

Currently refactoring, the solution just jumped in my face. Instead of having things like NetConnectionPool that is a resource containing all the connections, then try to bind that to a NetIdentity or whatever the heck I was doing, I'll just create an entity and put all the things the connection OWNS on the entity. Not sure why I'm so blind that I didn't see that before.

Collaborator

jojolepro commented Jul 9, 2018

Currently refactoring, the solution just jumped in my face. Instead of having things like NetConnectionPool that is a resource containing all the connections, then try to bind that to a NetIdentity or whatever the heck I was doing, I'll just create an entity and put all the things the connection OWNS on the entity. Not sure why I'm so blind that I didn't see that before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment