Skip to content
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

Stream basic unit information (name, type, position) #8

Closed
rurounijones opened this issue Jun 13, 2021 · 3 comments
Closed

Stream basic unit information (name, type, position) #8

rurounijones opened this issue Jun 13, 2021 · 3 comments
Assignees

Comments

@rurounijones
Copy link
Contributor

rurounijones commented Jun 13, 2021

EDIT

I think the easiest thing to do so far is to just use the MIST code where the lua will literally just be reading the mist.dbs.aliveUnits table, maybe converting them using the existing exporters and returning the table with the exported versions.

The question is how to have the rust code call this method on a timer and stream the objects to all clients. Since this is rust area I have very little idea of what needs to be done


Putting this in a Github Issue for discussion and brain storming.

We would like to export unit position information as a gRPC stream to clients. We want to do this in a way that does not block the lua thread in large missions. We want to do it at a use specified refresh rate which would be coarse to the level of something like every 1 second at highest refresh rate but could be as slow as every 10 seconds.

Looking for ideas since some of this will require more rust coding than just acting as an RPC interface I think (The perform in chunks option especially).

The basic process is:

  1. Client calls the RPC with desired refresh rate
  2. Call coalition.getGroups for coalition 1.
  3. For each group, call getUnits and add to a lua table
  4. Return the lua table to the rust code that streams each entry after serializing it
  5. IF coalition == 1 then GOTO 2 for coalition 2
  6. Sleep until refresh time and GOTO 2

This will work but it will get all units for each coalition in one go which may end up being many units and that could block the lua thread.

Possible ways around this....

Perform in chunks

  1. Client calls the RPC with desired refresh rate
  2. Call coalition.getGroups for coalitions 0, 1, 2 and add to a united groups table which is returned to rust
  3. For each group call Group.getUnits and return a lua table that contains the units to the rust code that iterates and serializes and streams each unit.
  4. Sleep TIME_REMAINING_UNTIL_REFRESH / GROUPS_REMAINING in rust.
  5. IF GROUPS_REMAINING > 1 GOTO 2 ELSE SLEEP TIME_REMAINING_UNTIL_REFRESH THEN GOTO 2

Use lua coroutines

This is the same as the basic process but we use lua coroutines and add some yields in the code when it iterates groups (or even units). I have no idea if coroutines will work as expected when the method is being called from rust or even if they will work properly.

We could look at how MIST does it ( https://github.com/dcs-liberation/dcs_liberation/blob/b8e6c2fe78ca3a3d49d302239403777e46bd12ad/resources/plugins/base/mist_4_4_90.lua ) or even just use MIST for the implementation by default.

Other things to think about

  • We could split by category as well and only do aircraft every X time while ground units would be every 5*X since they do not move as fast. This is what Tacview does (Just at a much higher rate for both).
  • We could ignore weapon objects entirely unless the client specifies weapons are in scope.
  • What if multiple clients call this API. We want to fanout the data to all of them, maybe that means no per-client configurable refresh rate.
@rkusa
Copy link
Collaborator

rkusa commented Jun 17, 2021

Kudos for putting a lot of thought into this! 👍

The basic process is:

  1. Client calls the RPC with desired refresh rate
  2. Call coalition.getGroups for coalition 1.
  3. For each group, call getUnits and add to a lua table
  4. Return the lua table to the rust code that streams each entry after serializing it
  5. IF coalition == 1 then GOTO 2 for coalition 2
  6. Sleep until refresh time and GOTO 2

This will work but it will get all units for each coalition in one go which may end up being many units and that could block the lua thread.

This actually sounds good to me. I am not worried about blocking the luau thread, since we currently only execute at most 10 RPC calls at once and then wait ~0.02 seconds before executing the next calls (10 at most again). 10 at most and 0.02 seconds is quite arbitrarily choose right now and can be fine tuned in the future.

I think this solves most of the concerns and challenges you've mentioned, right? It still has a drawback, getting the response as a client is not "instant".

I think the easiest thing to do so far is to just use the MIST code where the lua will literally just be reading the mist.dbs.aliveUnits table, maybe converting them using the existing exporters and returning the table with the exported versions.

If going this direction, I'd actually prefer to maintain a list of alive units inside of the gRPC server. This would mean to re-implement what mist already did, but we'd be able to offer access to this information without any roundtrip to the mission env.

@rurounijones
Copy link
Contributor Author

rurounijones commented Jun 17, 2021

I am fine with either direction. Altough I agree that avoiding a trip to the Mission Env would be the best option if we can get away wtih it but not sure how that would work with updating unit positions.

Are you ok to take on this task? I am still at 0 level of knowledge for Rust which scupper anything I can do.

I have started filling in information for the event stream objects in #9 which may help with this if you choose to go the second route.

@rurounijones
Copy link
Contributor Author

The bulk of this hass been implemented in the above commits. #20 covers the one outstanding issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants