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

Entertainment thread safety/API issue #209

Open
ermau opened this issue Jan 7, 2020 · 2 comments
Open

Entertainment thread safety/API issue #209

ermau opened this issue Jan 7, 2020 · 2 comments

Comments

@ermau
Copy link
Contributor

ermau commented Jan 7, 2020

EntertainmentLayer inherits from List<EntertainmentLight>, exposing direct access to its own storage. However, within AutoCalculateEffectUpdate, it delegates work to another thread through Task.Run and reads through the same storage that it exposes without any locking mechanism. It does the same thing with Effects. If you call AutoCalculateEffectUpdate and later add an effect or remove a light, you may crash if the started task is reading at the same time you're writing.

Normally you could just add some locking around this, but since the storage mechanism is exposed, the user has no way to participate. I would have just submitted a PR, but I think the problem necessitates a breaking change to the API. I've done that in the past, but that was far earlier in the library's life so I wanted to start a discussion first as this same problem also occurs in other APIs.

I'd recommend avoiding inheriting directly from concrete collections for public API types in general, it locks you in to the type or forces you to make a breaking change if you have to change things later.

@ermau ermau changed the title Thread safety/API issue Entertainment thread safety/API issue Jan 7, 2020
@michielpost
Copy link
Owner

Thanks for the suggestions. Certainly valid points and I've come across these threading issues myself in the past while working on HueLightDJ.

So if I understand correctly, you're suggestion is to not expose the Effects property, but require the usage of methods like public void PlaceEffect(BaseEffect baseEffect).
And EntertainmentLayer should not inherit from List<EntertainmentLight> but keep that storage in a private property.

If you're willing to submit a PR, that would be great. I have no problem with a breaking change if it's for the better. The Entertainment API is not as widely used as the default HTTP api, so the impact won't be that big I think.

@ermau
Copy link
Contributor Author

ermau commented Jan 8, 2020

So if I understand correctly, you're suggestion is to [..]

Yeah at first glance, basically.

If you're willing to submit a PR, that would be great. I have no problem with a breaking change if it's for the better.

I'll go ahead and start on a PR.

I'm not familiar enough with the API yet to know what is need or isn't, so I'll have to pop back in with questions as I go. For example, is it a purposeful decision to allow the user to add and remove lights to a StreamingGroup? How about for an EntertainmentLayer?

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