Closed smithed closed 10 years ago
I agree Modules should have no notion of Tags. The module should only be concerned about its Channels. As tags are only part of the Engine. If a Module has the concept of tags it cant be used without an Engine, limiting its reuse.
Modules DO have a notion of a Tag in their editor nodes. Almost every Module created so far does. If they didn't, they wouldn't ever use any of the mapping functions in their code. We could require that all mapping gets done inside of the mapping UI, but think about how nasty usability for that would be for a module like CVT. First users would have to create this long list of channels in one view, and then map them all to tags in this other. I think we can draw the channel/tag divide in the configuration and runtime classes of a module (as we already have), but allow people to assume that there will be an engine in their editor node code (because as far as we know there always will be).
If we are going to let users create their own tags from within an editor node, I think its good to also give them the ability to manage those tags. If the biggest problem with this feature is usability of the API which is what the negatives listed above suggest, then I would much rather find a solution that makes the API easier to use instead of removing the feature.
Also just to clarify, I think this feature adds value because it greatly expands a developer's ability to customize the behavior of the editor for their end users. Developers can use this feature to help prevent their end user's from messing up a configuration, or enforce specific static configurations for certain projects.
So I don't have a problem with the modules knowing about tags, although it would be nice to buff up the mapping window a bit more.
My problem is that I don't see a specific use case for this feature, and what you said (while true) is not a use case.
Here are a few potential use-cases that I can think of. I will also add that OtherDan has a lot of experience building this type of code in other modules, and this was high on his list of features that would be good to provide that similar tools don't.
This feature could be incredibly helpful for building a configuration editor targeted at a technician. The system developer could define a set of tags as static, but still allow a technician to add additional features like logging or web publishing for debugging. In cases like that, I can see a lot of value in having a configuration editor that is flexible to some types of change, and very resistant to others.
Also we could use this feature of a Tag owner to build in additional features. If two modules are supposed to have a direct data correlation (lets say a motion trajectory generator module and a motion I/O module), the consumer of that data (the I/O) could use the id of who created all of the necessary tags (the trajectory generator) to automatically determine which Tags to map to.
My personal feeling on this feature is that knowing who created a tag and limiting who has access to change a tag adds a lot of potential power and flexibility for very low cost. I am not disputing that the API as-written isn't misleading. However if the problem is simply that people aren't wiring what they really intend to an input, why can't we focus our efforts on how to solve that problem instead of removing the feature entirely? Are there currently any other costs of this feature outside of the usability?
Re P3: We don't actually keep a record of who created a tag (as far as I know) unless they also own the tag, so thats something you should consider. I personally don't think thats important, as a paired module should look for other nodes of the appropriate class (ie Sr. Trajectory looks for Mr. motion I/O and then asks it what channels it has, and then looks for tags mapped to those channels, and then maps its own channels to those tags).
Thinking about it some more, I still think that benjamin is right in the spirit of the thing. I remember we talked about this long ago, but the idea of exposing tags to the user just seems like a bad idea. Channels should map to channels. CVT shouldn't be logging the tag Mod1/AI0 to disk, it should be logging the scan engine channel Mod1/AI0 to disk, which is provided to it by virtue of the engine generating a tag. Admittedly none of the editors work this way right now, but this discussion is long-ish term and I'm talking about the ideal, not the reality. -> Technically the engine could just manage channel mappings, and not even have the concept of tags. This would reduce the number of data copies, but possibly result in cache misses if we are pulling in data from all over memory.
Finally, re the general argument: I realized when reading your description that this tag ownership thing doesn't actually do anything -- its a false sense of security. Just being sure your module is mapped to a tag doesn't mean the tag is mapped to anything else. At present we don't have a way to actually enforce what OtherDan wanted. What has to be done is enforcing that a particular channel to channel mapping can't be deleted, like from MyControlModule to MySimulationModule.
You are correct that there currently is no record without the owner. In the motion case, having an owner is good, because if a user makes a change to a single tag from the tag view then they would break the code. In that case it is really more of a channel collection that should be created, deleted, mapped, and modified together in order to work properly. The Owner is a potential mechanism to enable that functionality, but I don't think it would be the ideal one.
The trouble we ran into with the channel-only view of the world is that we would want Aliases anyway, and that creating channels in something like CVT to then go an map to a different channel in a different module is painful. We do need an abstraction that modules can talk to so they don't talk to each other. The concept of a Tag, while possibly not ideal, is an abstraction that was easy to implement and not too hard for people to understand. I agree that there should be a more ideal solution though.
We could instead have a channel registration system, but then the abstraction has to know about each channel and when it gets changed. I think that model made configuration changes much harder to manage as well.
Back to the original discussion, I think you have excellent points that the owning ID is not an ideal way to solve any of these use-cases, but I would still rather leave it in until we come up with a better approach.
Benji and I were talking about this on the way out (the aliases/CVT use case in particular). I think that this would not be any different in a tag-less view of the world. The CVT can ask the engine for any unmapped output channels and generate equivalent input channels. The CVT can ask the engine for any and all input channels, and generate equivalent output channels. The API wouldn't actually be much different (and it may even be simpler, since we push more work at the engine), and the behavior from the POV of the end user would be the same. The only difference is that the CVT name would match the channel name, not the tag name. I think this is generally ok (TDMS and Tag Bus Web would be fine with this situation) and for CVT there is nothing saying we can't change the name of the local channel, its just that so far we have fixed our channel name to match the tag name. ->Tl;dr: It shouldn't be any different in actual use for this particular situation.
As far as being hard to manage--we should talk about that some more. I actually think it would be simpler to manage. Right now a lot of modules, like CVT, are linked to tags. then those tags are linked to actual real data that matters. If I delete the real data, I don't want the CVT channel anymore but the tag in the middle serves as a buffer. I realize this buffering goes both ways, and some things are easier because of it, I just think that on the whole it would be easier to handle without the tag existing as a concept.
Finally, I'm fine with leaving it for now (and everything else we've been talking about). This is me just starting to talk about v2.0, not saying we need to fixit right this second.
I decided I'm OK with the idea of tags in the engine, but I would possibly like to do what we discussed and add both forms of API into the engine parent. By "both" i mean Channel -> Tag -> Channel as we have now as well as Channel -> Channel, which the engine API would then interprets as "make a tag, then map both channels to the tag". Thinking about it I agree that the tag in the middle adds flexibility, so the real solution is improving the API.
I did some benchmarking on the module to module concept. I couldn't think of a way to do channel->channel data transfer without copying a lot of data. I think its because LabVIEW thinks of clusters and arrays as coherent identities and doesn't like the idea of modifying one element while leaving everything else the same and writing the modified element back into the array. It could be in-place for sure in a c but I don't know how to do it in lv.
When the engine API decides to "make a tag, then map both channels to the tag." does the user get to see this newly created Tag in the Tag view, or we do hide it from them?
Also also, if an output requests to map to an input, then I assume the engine should see if that input channel already has a tag mapped to it and should simply map the Tag instead if so?
Today we have the concept of getting available Tags for mapping. Would this function now also return available channels?
I agree that this functionality would be nice to have, but I am worried that some confusing behavior could occur if we don't properly plan for how things should behave.
1-> See it in the tag view, it would just be made automatically
2-> Exactly, the point is to make the API smarter not change how the backend works
3-> Good question. One option would be no, but we'd have a new API call to get available input channels. I think this makes sense, since its really what we're asking most of the time. On the other side, you could say yes, it would return any tags and any channels which are not yet mapped to tags. But these two outcomes are basically the same. I think having two functions is easier, as you may actually only want things which have been mapped to tags already.
4->Could be, but I think it would help us move towards the idea you were talking about with varieties of modules -- some are producing, some are function oriented, some are tag oriented, some consume tags, etc..
@becega @Beazurt I want to list out the reasons why we have these features. That I know of: (+) OtherDan asked for it as a component of the "fixed channel module" concept
(-) Everyone who tries to use the API wires that field up, which causes issues in many cases (-) Fixed channel module doesn't require this feature (-) Confusion between the instance ID for mapping and the owning ID for tags