Naming Bi-Directional Streams In an API?
DingoTango writes "My coworker and I are designing an infrastructure API to manage data streams. It will allow a client developer to set up streams going to and from some invoked server functionality, and allow a server developer to write services that both consume and produce streaming data. Our quite civil disagreement involves naming: From the perspective of the client platform, the client's output stream goes to the server, and input stream comes from it. For the purpose of any ensuing discussion, let's call this the 'Local' perspective. However, if the client developer considers the service to be a widget, then the stream going to the service is the input stream and the stream coming from it is the output. Let's call this the 'Widget' perspective. As this is an infrastructure utility, we aren't able to name the streams according to function. What say ye, Slashdot? Is there any precedence, experience, or ungrounded yet vociferous opinion that will resolve this for us?"
Use foo and bar. Everyone understands that.
Why not call them the "client to server" stream and the "server to client" stream?
Or name the first one "not_fast" and the other one "enough"
Look at the purpose of the streams. Possible options are "request"/"reply", "control"/"media", etc.
UploadStream: data goes to a server.
DownloadStream: data goes from the server.
Just as described in some of the prior posts, I'd prefer UploadStream and DownloadStream. But if for some reason you don't want to use those names, how about StreamToServer and StreamToClient ?
Look from each component and the input and output streams based on that.
The client's output stream is the server's input stream, the server's output stream is the client's input stream.
The widgets output is the clients input and the widget's input is the clients output.
Yeah...
The syntax from socket programming, like send, receive, and listen, seems well suited for situations where both sides can act as clients or servers. Both sides would use the same syntax, each naming things from its own perspective.
...I think you want StackOverflow which is a few clicks that way ------>
...but the SEND/RECEIVE pins between modem and computer are always named from the perspective of the computer. There's precedent to use server-centric nomenclature.
Matthew G P Coe
http://mgpcoe.blogspot.com/
I can definitely the benefit of names pairs such as "Upload"/"Download" or "toServer/toClient" or "toServer/fromServer". Those all work when you've got a clear client/server orientation. But, if you're talking about more distributed situations where you have more of a peer orientation, those break down.
If you can name them separately in the client and in the server, why not use names that are meaningful to the local context? For example, the client's output stream goes to the server's input stream, and vice versa? You've got good precedent for that today in UNIXland with stdin and stdout. Consider a pipe: One side writes to its stdout, and the other side reads it from stdin. Seems perfectly logical to me.
Program Intellivision!
Indeed, upload and download were highly directional and even connotated the initiator. Unfortunately the terms have become corrupted where an upload became synonymous with outgoing data transfer and download with incoming data transfer, and both terms being applied to the same transfer, disregarding the initiator (particularly in torrenting software).
You push a file: you send an upload, the remote machine receives your upload; you pull a file: the remote machine sends you a download, you receive that download. The data stream is either an upload or a download depending on whether it is a push or pull. Either result could be incoming or outgoing to your local machine depending on which machine you're controlling. Thus torrenting is always a download, never an upload. Actual uploading only occurs for services that accept unrequested files like an FTP server that allows you to PUT files.
Uploads and downloads are data streams, not command streams. You would not apply them to a telnet session.
Unless you're NASA. Then uploads are against Earth gravity and downloads are towards Earth gravity regardless of anything else. In future, NASA will have to generalize that to other gravity wells.
I'm going to assume your server accepts all input given it and produces output for all input and there isn't a command and control interface, or at least not at the immediate level.
Here your data streams are I/O with an operation occurring on an external device. We'd call it a peripheral if it weren't over a network. We never call moving data to/from a disk to memory uploading or downloading: that's saving and loading.
If you need to call attention to the network, this would be a reciprocated stream: sending data (not strictly a command) to the server will result in a returning stream of data. If your server exists to serve the requests of the client and initiates no data, you're uploading a stream to the server and receiving its output. The output is a product of your upload, but it is not your upload, nor is it a download; it is the reciprocal response to your upload. It could be a simple as a reflector returning your input to you unprocessed or doing a rot13 on it. Practically a telnet-like service, full duplex.
If you consider the UNIX pipe, it connects the input of one command to the output of another. Something provides the initial input and you will end up with a final output. Whether the client considers its outgoing stream its output locally or the input to the server "widgetally" doesn't matter, as both are correct. What is outgoing from the client is incoming to the server. What's to prevent your client from being another server? Or feeding back between servers?
If you need a term that identifies a stream uniquely regardless of perspective of client or server, you need to define it from an initiator's perspective like upload and download were. But be aware, eventually people will cease to care about the difference. Eventually it will devolve into questions of what is incoming and what is outgoing from their own perspective at a particular node. You might as well call them incoming and outgoing, especially if one's output can become another's input (or even your own).
(Linguistically, is there a difference between incoming/outgoing and ingoing/outcoming? Other than ingo isn't a noun like outgo and income, and outcome isn't a verb? The latter also seem vaguely biological to me.)
Oh, say does that Star-Spangled Banner entwine / The myrtle of Venus with Bacchus's vine?
although "eat me" "drink me" is a close second
why not produce(er) and consume(er) as in the messaging world?
or is that too obvious?
Mission: To provide products that consume time and energy as entertainingly as permitted by the laws of thermodynamics.
Media frameworks such as DirectShow, GStreamer and the such are quite good at this. I work on this specific type of code all day long and maintain my own alternative for extremely high bit-rate environments.
You're talking about designing an object that consumes and produces real-time data. The source of this data is provided by an "upstream" component (or object to be consistent) within your processing pipeline. The destination for the data produced is provided to a "downstream" object.
An API for this type of component should always been seen from the perspective of the user of the component or object. Therefore the interfaces should be named NOT from their internal perspective, but from their external perspective. After all, your APIs are theoretically there so that someone else can use your component without being familiar with the internal architecture of the component itself.
An upstream component which provides data to downstream components are "Data Sources".
A downstream component which consumes data provided by "Data Sources" are "Data Sinks"
A component which acts on data received from an upstream "data source", alters it or produces new data from to send down stream to a "data sink" is called a "transformation" object.
So, a processing pipeline should consist of 3 elements.
1) Data source
2) Transformation Object
3) Data sink
This is similar in nature to :
1) Input
2) Process
3) Output
Though in an object oriented model making use of a pipeline style pattern, it's best to name the objects appropriately.
The output of an object, or the API of an object which provides data to downstream elements, components, objects (etc) should be referred to as Source. So a "Source Object" outputs its data through a "Source". In GStreamer for example, you would say "The source element provides data to downstream elements through one of its source pins" as GStreamer (like other pipeline architectures) provides a uniform interface for providing and consuming data.
The input point of an object (which receives data from upstream objects) should be called a "Sink".
A transformation element contains a minimum of one source and one sink. Data is received by the object via its sink and the processed data is pushed from the object via its source.
This methodology is very simple to use and understand.
An alternative can be "Receiver" which suggests the object received media via this interface and "Transmitter" which suggests that the object transmits data from the interface.
Some people like to use "Listener", "Observer" etc... but since there's no nice corresponding opposite to either of these, I find them grotesque when I encounter them in code.
I think that if you read up on the GStreamer documentation web site, you'll get some great ideas for how best to handle this. Just remember that when you're providing an API to a customer, you're delivering something that should be easy to use and understand from their perspective from the outside. Your API naming should reflect this.
.... Sink and Source?
name them from the perspective from which they're used from the api. that is, functions that take data to be sent elsewhere would be named 'send'(or upload) and 'get','receive' or similar would be the other direction.
but this seems like a case of where they should have just named them john1 and doe3 or _anything_ so they could have moved on with their design, if things go this way then next week they can argue about package names.
world was created 5 seconds before this post as it is.
The server just happens to be a well know location for a service that can be connected to. The client initiates the connection. Once the connection is establised the "server" and the "client" effectively become "clients" of each other, when the output of one is plugged into the input of the other.
For example, in .net land (it's where I am, forgive me) you have a TcpListener on the server side. Then when a client connects using a TcpClient, the server creates a corresponding TcpClient on the server side. Writing to the client's TcpClient.Stream will allow you to read from the servers TcpClient.Stream, and vice versa.
Your API should probably be considering the establishment of the connection, rather than the connection itself.
Rocket science is easy. Neurosurgery, now *that's* difficult.
You guys are setting up a post for a story about naming conventions, when we have so many other news posts that could take precedence.... ...here is one, whatever the providing server's owner decided....as it is they that pay the bills for the server and the in house development, so if they feel like calling the service or widget, porky_pig-IS**my_(FRIEND)....who cares....
When both sides produce and both sides consume, the words "producer" and "consumer" aren't exactly as appropriate.
Think of use cases. What are the clients of your API be doing the most?
What choice will cause the least astonishment to your users?
This is a usability problem. Do what will confuse your user the least. Ask them if you have to.
Write code for both cases against your API. Use it and see what works and what doesn't.
There is no easy answer, this is a design question and aesthetics matter, hence it's rather subjective.
In any case, take into account if your target development platform uses any conventions, and if so stick to them.
I have 3 questions:
1) Why isn't this the highest modded comment in the thread?
2) Why are others continuing to post after this solution? I mean, why would you do anything other than name the stream coming in to the server as the input stream in the server context, the stream coming from the client as the output stream in the client context, and so on?
3) How long until the entire project crashes in complete disaster? Does it really take 2 developers to figure this out? The only other scenario I can think of is the grown ups are finishing the project while these 2 kids are on a snipe hunt.
Does it really take 2 developers to figure this out?
No, one developer on their own would have figured it out. It takes two developers to make it an issue. ;c)
At first, I didn't understand what all the fuss was about, because I gathered that the server functionality always behaved like a filter. If that is the case, then just treat it like a black box; don't even muddy the waters with the fact that this box is doin' its thing "out" on a server somewhere else. The stream I feed it is 'in', the stream it gives me back is 'out'. No big deal, whether I am developing the client or the server.
But if the client will sometimes send a stream off, expecting nothing in return, then maybe 'in' doesn't make sense? I dunno. It is a convention. People establish conventions so that semantics are predictable, and good conventions align with the user's intuition. If the intuition of users or developers happens to clash, then they ought to just pick something and be done with it, then get accustomed to it. If it moves things along, I am of the crowd that says, "Call one way 'TweedleDum' and the other 'TweedleDee' and get on with your lives."
Words give you power.
I have not used it, but I think that OSCgroups does some related things with passing messages and streams to disparate clients and servers, and if one roots through the codebase it is possible that there might be some interesting conventions there.
... so just pick one and stick to it.
I'm partial to "input" and "output" myself, from the perspective of the object using them (so a client's output goes to the server's input and vice-versa).
If you need to reference both objects' streams at the same time, you've got "myInput", "myOutput", "hisInput", and "hisOutput" for clarity.
Or just pick something fun; "spinwise" and "widdershins" isn't bad, but may confuse your users.
Bravery is not a function of firepower.
~J.C. Denton (Deus Ex)
The InputStream is the one being read from and the OutputStream is the one bing written to. The same stream will be called both depending on which side you're looking at.
I think I see your dilemma. If I understand correctly, you are examining the perspective of the client developer that might approach the server in client-server mode, in which case upStream/downStream (or something of that nature) would work nicely. Conversely, the client developer might be working with a widget that appears to him/her as any other client side object. In this case you can use in/out terminology and simply forward the call to the up/down methods respectively. Interesting names could also be ears/mouth, mike/speaker, reader/writer, etc.
sigo ergo sum