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

`ReadableStream` vs `progress` Event vs both #27

Open
adrianhopebailie opened this issue Oct 14, 2019 · 19 comments
Open

`ReadableStream` vs `progress` Event vs both #27

adrianhopebailie opened this issue Oct 14, 2019 · 19 comments
Labels

Comments

@adrianhopebailie
Copy link
Member

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

From web-monetization created by sublimator: adrianhopebailie/web-monetization#25

@marcoscaceres and I started discussing this in brief in #24

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

I think what I'm drawing out of that comment is that the "content creator" site might actually want the ability to "pause" a stream as well?

So someone goes to mymoneytube.com and is playing some songs, they press pause for a bit, and then without having to also pause separately as part of some external WM controls, the stream is paused ?

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

Yes, precisely @sublimator. @adrianhopebailie, was there some rationale for not really supporting the above in the current design? Was it just for simplicity? I think it could be possible to support both models in the spec... the declarative model could just be "pay me now!"... while the . monetization. object could provide a means for finer-grained control.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

I think I recall you mentioning something about (edit: use backquotes for <link>) <link> tags instead of meta. I've not really let myself think much past the current design, but vaguely pondered some kind of container tags for monetized content. Think like a scrolling page of videos / images.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

Ah, that reminds me... we need to add SecureContext to the IDL interfaces to make them only exposed in HTTPS.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

Was it just for simplicity

@sharafian / Ben wrote most of the spec. He's still traveling Japan :)
But I get the feeling, yes, it was all kept quite simple. Simplicity/Complexity infects everything.
At first the tags were meant only for static, server sent (ideally via https) documents, where the stream would just start and last for the lifetime of the page.

Later we added a MutationObserver observer to the head, to support the coil.com SPA site.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

I'm envisioning a case where the content publisher only wants to monetize when the user is interacting or consuming a particular content: for example, the user starts actively engaging with some media (audio, video, canvas, whatever). The user might pause the media, hence the monetization stream could also be paused and resumed.

Streams seem well suited to model the use case above, as opposed to the current eventing model where money just floods in irrespective of what the user is doing. From this perspective, a stream API might give content producers and users better control over negotiating how payments are streamed and a better sense of control over what the user is paying for.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

There were some norms in the music industry that 30s preview is free of charge(or varies in the duration), so there was samplings edition that users can freely try and decide. For music, which we are working on( github.com/musiocin), the technical model is to stream it, but the consumption model can be different from service to service, e.g. charge by traffic or minutes, or track, etc. The key challenge is not on how to trigger the payment, is on how to validate the playback and how flexible a contract can be hooked behind.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

There is a reasonable example on MDN that shows how they work with a fetch request's body:
https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

Thanks @immartian for the clarification. I'm still wondering about the flexibility afforded by streams over events. At first glance, it feels like streams provide more flexibility and control to all parties than the eventing model, but still something we would need to explore in detail.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

I still don't grok how streams in the browser work, esp. for things other than streams of data. are there any good explanations online of how streams API works?

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

We were thinking of this in terms of incentives when we wrote the spec initially. Even if a user isn't actively streaming content, the site should still want to monetize the user's time on the page. The idea that the user or site would want to not monetize suggests that there are flaws somewhere else in the design of Web Monetization: the goal for WM to be a frictionless way for a site to monetize that doesn't require user consent and shouldn't worsen the user's experience in any way.

That said with the ability to dynamically add/remove the meta tag you can turn monetization on/off at will. We may want to add an imperative API (document.monetization.stop(), document.monetization.start(paymentPointer))in addition to the declarative one because dynamically adding/removing meta tags all the time can get a bit janky.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 14, 2019

I think it would be useful to show a code example of consuming a stream vs events.

Here's my best effort.

This assumes that we'll have something like monetization.paymentStream that is a ReadableStream which is a stream of objects that each represent a successful payment.

let pause = false;

window.addEventListener('load', startPayments);

function startPayments() {
	pause = false;
    handlePayments(monetization.paymentStream.getReader());
}

function pausePayments() {
	pause = true;
}

function handlePayments(reader) {
    reader.read().then(
        ({ value, done }) => {
            if (done) {
				// The stream was closed, this is a terminal event (i.e. not paused)
                console.log(`The stream was closed!`);
            } else {
                // Handle next payment
				console.log(`Got paid ${value.amount}!`)

                if(!pause) {
                    // Recursively call
                    handlePayments(reader);
                }
            }
        },
        e => console.error(`The stream threw an error.`, e)
    );
}

I assume this will be even cleaner with async iterators

@adrianhopebailie adrianhopebailie changed the title Pros/Cons of Streams vs Events `ReadableStream` vs `progress` Event vs both Oct 15, 2019
@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 15, 2019

PROPOSAL

Based on the discussion so far we should at least add a ReadableStream to the interface that websites can use to read incoming payments.

We can leave the events too and see which developers prefer over time.

We should do this as part of the global interface (See #24)

Please respond to this proposal with either an 👍 or a 👎

If you are 👎 on this proposal please provide rationale below

@sublimator

This comment has been minimized.

Copy link
Collaborator

@sublimator sublimator commented Oct 15, 2019

While I haven't personally been attracted to what I've read/seen so far, I'm in favor of trialing a Streams interface simply by virtue of others wanting it. Again, I think a Preview/Next/Alpha/Whatever release track would help here, so we can experiment and get feedback.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 15, 2019

I think a Preview/Next/Alpha/Whatever release track would help here, so we can experiment and get feedback.

Can you say which features you think would be in this track and why they can't just be deployed in the main track?

@sublimator

This comment has been minimized.

Copy link
Collaborator

@sublimator sublimator commented Oct 15, 2019

@sharafian

This comment has been minimized.

Copy link
Contributor

@sharafian sharafian commented Oct 15, 2019

👎 Not sure how we'd actually map a ReadableStreams API to the WM api

STREAM doesn't have any concept of packet-based backpressure, only amount-based backpressure. And we don't want the site to have to specify the amount when it uses the iterator so really a time-based start/stop is all we can practically do. Basically the mapping from iterations in the web streams API doesn't map to anything in the STREAM protocol nicely.

@adrianhopebailie

This comment has been minimized.

Copy link
Member Author

@adrianhopebailie adrianhopebailie commented Oct 16, 2019

Not sure how we'd actually map a ReadableStreams API to the WM api

I think this is worth exploring but I'd guess something like adjusting the maxReceive between 0 and MAX depending on whether or not someone is reading the stream.

@sharafian

This comment has been minimized.

Copy link
Contributor

@sharafian sharafian commented Oct 16, 2019

You can't decrease receiveMax. I suppose you could sever the stream as a "backpressure" mechanism but then we waste a tremendous amount of time reopening it and closing it if someone has written code that requires us to wait

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.