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

ReadOnlyBroadcastChannel #532

Closed
brettwillis opened this issue Sep 7, 2018 · 1 comment
Closed

ReadOnlyBroadcastChannel #532

brettwillis opened this issue Sep 7, 2018 · 1 comment

Comments

@brettwillis
Copy link

Consider the use case when an API/library exposes a channel that will be consumed in multiple locations within an app.

I have implemented this pattern as something like this:

class DataSource {
    private val _data: BroadcastChannel<Data> = ...
    
    // Public API
    val data: ReceiveChannel<Data>
        get() = _data.openSubscrption()
}

This is risky, as it is not obvious to consuming code that data returns a new channel instance which must be cancelled every time.

Another way is like this:

class DataSource {
    private val data: BroadcastChannel<Data> = ...
}

Now it is obvious what is happenning, because the consuming code must call openSubscription() itself. However, the downside is that consuming code can close or even inject elements into the BroadcastChannel which may break the API.

I propose to create ReadOnlyBroadcastChannel<E> and then modify BroadcastChannel<E> to inherit from ReadOnlyBroadcastChannel<E>, like so:

interface ReadOnlyBroadcastChannel<E> {
    fun openSubscription(): ReceiveChannel<E>
}

interface BroadcastChannel<E>: ReadOnlyBroadcastChannel<E>, SendChannel<E>  {
    ...
}

This way the library API can become like this:

class DataSource {
    private val _data: BroadcastChannel<Data> = ...
    
    // Public API
    val data: ReadOnlyBroadcastChannel<Data> = _data
}

Now, the BroadcastChannel is safe from being modified by client code (of course it can still be type-cast...), and the usage of the api is clearer.

@elizarov
Copy link
Contributor

elizarov commented Sep 7, 2018

Thanks. This is a duplicate of proposal and discussion that is happening in PR #274 and we had postponed the resolution until we have design for cold-stream abstractions (see #254), so I'm closing this issue.

@elizarov elizarov closed this as completed Sep 7, 2018
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