This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.

Bug 19762 - "connect" event not logically possible, and disconnect message not present on some systems
Summary: "connect" event not logically possible, and disconnect message not present on...
Status: CLOSED FIXED
Alias: None
Product: AudioWG
Classification: Unclassified
Component: MIDI API (show other bugs)
Version: unspecified
Hardware: All All
: P2 normal
Target Milestone: TBD
Assignee: Chris Wilson
QA Contact: public-audio
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-10-29 19:44 UTC by Chris Wilson
Modified: 2012-12-11 09:46 UTC (History)
2 users (show)

See Also:


Attachments

Description Chris Wilson 2012-10-29 19:44:43 UTC
The "connect" event as currently spec'ed isn't possible to receive (since it fires on the MIDIPort, which the user wouldn't have been able to create yet, since it's not connected).

'disconnect' is also hard if not impossible to implement on some systems.  Suggest cutting the events.
Comment 1 Chris Wilson 2012-10-31 19:53:52 UTC
Removed connect/disconnect events - https://dvcs.w3.org/hg/audio/rev/46c470599a4b - for simplicity reasons in v1.

The current model for input and output ports is similar to the Windows MIDI model, or the CoreMIDI model of Source and Destination iteration - NOT CoreMIDI's "GetDevices" model, which includes offline devices.  (Windows does not include a similar model.)

In order to add connect and disconnect events, we would need to:

1) define the lifecycle of a MIDIPort (actually, a MIDIInput or MIDIOutput) - that is, state what happens when it goes offline and then comes back online, or what happens if you ask for getInput and hand a reference to a port that has gone offline;

2) have "connect" notifications fire on the MIDIAccess, so the developer would know that a new device has come online; optionally (depending on answers above) additionally fire that event on the MIDIPort itself.

3) "disconnect" should also fire on the MIDIAccess as well as any open instances of the MIDIPort - that would help developers know to update, e.g., a current "live list" of available MIDI ports.

4) Clearly state what happens when a reference to an offline MIDI port is handed to getInput or getOutput.

In looking at all these issues, it seemed much better to simplify the model in v1, and examine usage scenarios in the future.
Comment 2 Jussi Kalliokoski 2012-11-01 09:48:51 UTC
(In reply to comment #0)
> The "connect" event as currently spec'ed isn't possible to receive (since it
> fires on the MIDIPort, which the user wouldn't have been able to create yet,
> since it's not connected).
> 
> 'disconnect' is also hard if not impossible to implement on some systems. 
> Suggest cutting the events.

Not really true, these events are designed for easy hot-plugging of MIDI devices. If the program already has the MIDIPort, it's not going to magically disappear if the associated device gets unplugged, so the "disconnect" event gets fired, and when/if the associated device gets replugged, the "connect" event gets fired. While not all system APIs support this, it's fairly simple to achieve with polling, given that we place no requirements on how soon the event must fire, so that we don't place a performance burden on the user agent.

As for the 3), I think for the MIDIAccess interface, an event that fires whenever the ports list changes (merged disconnect and connect) should be enough.

BTW, I'm not very happy that you went ahead and removed them from the spec.
Comment 3 Chris Wilson 2012-11-01 15:05:46 UTC
First, my apologies for brusquely removing; I've had feedback that the more implementable the spec is, the easier it is to get implementation experience.

My comment on disconnect being challenging on some underlying platforms was referring to the fact that not all underlying systems fire disconnect events (e.g. Windows' MIDI API, outside of the apparently-deprecated DirectMusic APIs).  Although of course if you already had a reference to a MIDIPort, and it was disconnected then reconnected, you could get a connect event fired on the MIDIPort (see #2 in Comment 1 - "optionally additionally fire on MIDIPort itself".  However, that's frankly quite a narrow scenario, and it's more interesting to be able to get notifications for Ports you don't already have a reference to - e.g. to update a dynamic list of currently available MIDI ports, detect when a new controller has been plugged in, etc.  That would be much more of a core usage scenario for a connect event.

As to "not going to magically disappear" - I don't know, honestly; we have to explicitly define what happens in this case.  Would it be expected that the MIDIPort becomes "active" again (e.g. you start receiving messages on an Input, or you can once again send to an output) if it's unplugged and then replugged?  I haven't had a chance to investigate behavior in that scenario in Windows/CoreMIDI.

On merging connect/disconnect updates - I'm a little uncomfortable with that; it's  much easier to write code that detects and configures a newly-plugged controller, e.g., if you're told WHICH Port was added.  We could require the developer to hold on to the list themselves (i.e. there is a workaround), but it might be easier to provide this information in the first place.

If we are going to have these events, and are expecting polling to be used to implement them in a significant scenario (e.g. "on Windows"), we really do need to say something about such things as the latency of these events.  Polling every MIDI device in the system once a second to implement these events seems not necessarily worth it to me; but if we are doing that, we need to provide definitive guidance on this, and these events should be a "MUST" not a "SHOULD".

For all these reasons, I personally think we should postpone connection events to a later revision; but if you want to try to address this now I'm open to doing that.  However, what we had in there wasn't very useful, and it opened up more questions than it resolved.

The changelists (there are actually two, as I missed a section in my first update) are pretty easy to grab content from and push back in:

https://dvcs.w3.org/hg/audio/rev/46c470599a4b and
https://dvcs.w3.org/hg/audio/rev/b70563d39ab1

You can revert them, but then these issues need to get resolved in detail at the same time, and I maintain that the current text's structure (connect/disconnect fire on MIDIPort, not MIDIAccess) is not addressing the most important use case (updating list of accessible ports).
Comment 4 Olivier Thereaux 2012-11-19 15:56:22 UTC
Haven't seen any response to Comment #3 in about 2 weeks. Does it mean you're happy with it, Jussi?

Also, is this a case of issue being FIXED or more of a LATER - as in, we'd deal with connect/disconnect events in a later revision of the spec?
Comment 5 Chris Wilson 2012-11-19 18:03:11 UTC
(In reply to comment #4)
> Also, is this a case of issue being FIXED or more of a LATER - as in, we'd
> deal with connect/disconnect events in a later revision of the spec?

I think this can be left to later, if Jussi wants; I'm personally happy with the API without it.
Comment 6 Jussi Kalliokoski 2012-11-19 21:45:39 UTC
Oops, thought of this one so much that I forgot that I hadn't actually answered.

(In reply to comment #3)
> First, my apologies for brusquely removing; I've had feedback that the more
> implementable the spec is, the easier it is to get implementation experience.
> 
> My comment on disconnect being challenging on some underlying platforms was
> referring to the fact that not all underlying systems fire disconnect events
> (e.g. Windows' MIDI API, outside of the apparently-deprecated DirectMusic
> APIs).  Although of course if you already had a reference to a MIDIPort, and
> it was disconnected then reconnected, you could get a connect event fired on
> the MIDIPort (see #2 in Comment 1 - "optionally additionally fire on
> MIDIPort itself".  However, that's frankly quite a narrow scenario, and it's
> more interesting to be able to get notifications for Ports you don't already
> have a reference to - e.g. to update a dynamic list of currently available
> MIDI ports, detect when a new controller has been plugged in, etc.  That
> would be much more of a core usage scenario for a connect event.

I think that both of those cases (detect when a device is newly plugged in and detect when a device is replugged) are quite useful. I don't know about you, but for me it's about every other day that I setup my DAW and a virtual instrument just to notice that I forgot to plug in the MIDI keyboard (I don't exactly have a dedicated computer for making music), so I'll have to restart my DAW and either save my progress before it to keep going from where I left or do the setup again after the DAW is back on. Not such a great UX, and this is the norm (I honestly haven't used a single DAW that worked differently, but then again I have all my DAWs on Windows) when the APIs don't have a good way of detecting these things.

As for the hot-plugging scenario, ever used a DAW on a gig for the synth, then someone accidentally unplugs your USB cord with a guitar headstock and then that buildup just doesn't sound quite right without the synths, since you have to wait for the DAW to restart? Happened to me, and it's quite an embarrassing experience, really. As for the less embarrassing but still annoying and probably more common ones: you've setup your DAW (again) on a gig or at rehearsals and then that keyboard just isn't in the right place according to someone so you have to move your stuff and again we go with restarting the DAW (unless you were smart enough to prepare and didn't wire the keyboard through the stand, which however does make the first scenario more likely).

This really is the sort of thing you want the API to make easy for you so that most applications out there just work in these situations.

> As to "not going to magically disappear" - I don't know, honestly; we have
> to explicitly define what happens in this case.  Would it be expected that
> the MIDIPort becomes "active" again (e.g. you start receiving messages on an
> Input, or you can once again send to an output) if it's unplugged and then
> replugged?  I haven't had a chance to investigate behavior in that scenario
> in Windows/CoreMIDI.

Yes, this is how I've planned it.

> On merging connect/disconnect updates - I'm a little uncomfortable with
> that; it's  much easier to write code that detects and configures a
> newly-plugged controller, e.g., if you're told WHICH Port was added.  We
> could require the developer to hold on to the list themselves (i.e. there is
> a workaround), but it might be easier to provide this information in the
> first place.

Hmm. I doubt that the application doesn't already know all the relevant information about ports it's already using, so I think the listener for the event for MIDIAccess to notify about the list of available ports changed will mostly just scan the lists again to see if there are any devices that have a function reserved for them, but aren't assigned to that function yet. The event firing even when ports get disconnected is mostly useful to e.g. update a list UI to for picking the right port.

> If we are going to have these events, and are expecting polling to be used
> to implement them in a significant scenario (e.g. "on Windows"), we really
> do need to say something about such things as the latency of these events. 
> Polling every MIDI device in the system once a second to implement these
> events seems not necessarily worth it to me; but if we are doing that, we
> need to provide definitive guidance on this, and these events should be a
> "MUST" not a "SHOULD".

Agreed. On systems that require polling, I doubt that it makes sense to poll more often than once every 15 seconds or so.

> For all these reasons, I personally think we should postpone connection
> events to a later revision; but if you want to try to address this now I'm
> open to doing that.  However, what we had in there wasn't very useful, and
> it opened up more questions than it resolved.

You're right about the previous text not being very helpful, but I'd still like to pursue this. While we should learn from other MIDI APIs and it's true that the underlying APIs and many wrapper APIs have no support for this feature (without polling or other nasty solutions), I think in this case the thing to learn is to not repeat the mistake.

Personally, as a developer, I find it annoying that those features aren't there without jumping hoops. As a user, I find it annoying, because it affects the UX of programs I use. And allow me to use a lame joke here: "I'm glad the APIs don't let me know when relevant devices are plugged in" - No one, ever. I can't think of a single argument for not having these features in, from the API usability perspective, or from the user's perspective. Implementors' perspective, sure, any feature costs precious man-hours in implementation, tests, code review, QA and fixing bugs. However, this isn't especially complex to implement. Jumping hoops, sure, but I doubt that it even makes the list of 95% of the hardest web features to implement.

> The changelists (there are actually two, as I missed a section in my first
> update) are pretty easy to grab content from and push back in:
> 
> https://dvcs.w3.org/hg/audio/rev/46c470599a4b and
> https://dvcs.w3.org/hg/audio/rev/b70563d39ab1
> 
> You can revert them, but then these issues need to get resolved in detail at
> the same time, and I maintain that the current text's structure
> (connect/disconnect fire on MIDIPort, not MIDIAccess) is not addressing the
> most important use case (updating list of accessible ports).

Meh, don't worry about it, I'll need to write new text for it anyway. I was just surprised of the move without having myself had the time to reply to the argument made.
Comment 7 Olivier Thereaux 2012-12-11 09:46:30 UTC
Seeing agreement, closing. Still not 100% certain whether this should be FIXED or LATER, but will keep it as is.