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

Make text plugin's is_active method check for data in multiplexer first before checking plugin assets. #1021

Merged
merged 8 commits into from
Mar 15, 2018

Conversation

chihuahua
Copy link
Member

@chihuahua chihuahua commented Mar 5, 2018

We make the text plugin's is_active method return true if it detects
relevant data present within the multiplexer. Subsequently, there would
be no more need to check for data stored within plugin assets.

This solves an issue: The text plugin used to be inactive when the user
initially loads into it because the thread for computing whether the plugin
is active would not have completed executing yet.

Part of #625.

Test plan:

Run the text demo. Verify behavior. The text plugin should be active on
the first load.

We make the text plugin's is_active method short-circuit if it detects
relevant data present within the multiplexer. Subsequently, there would
be no more need to check for data stored within plugin assets.
Copy link
Contributor

@nfelt nfelt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the fix! I maybe would adjust the PR title slightly - the text plugin does already short-circuit in is_active(). What this PR fixes is that it always defaults to False on the first attempt; it can be smarter than that by checking the multiplexer first, since that part is cheap (it's just the plugin assets reads that aren't).


def _fetch_run_to_series_from_multiplexer(self):
run_to_series = collections.defaultdict(list)
# TensorBoard is obtaining summaries related to the text plugin based on
# SummaryMetadata stored within Value protos.
mapping = self._multiplexer.PluginRunToTagToContent(metadata.PLUGIN_NAME)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Augment the summaries..." comment a few lines down (grrrr github disallowing comments outside diffs) no longer applies here, it should probably be relocated - though I'm not actually sure introducing this helper is necessary? think the main thing is just checking the multiplexer in is_active(), otherwise index_impl() should work fine as is.

If we do keep the helper, the logic can also be simplified, this is pretty much just

return {run: list(tag_to_content.keys()) for run, tag_to_content in six.iteritems(mapping)}

I guess you're actually using the fact that it's a defaultdict(list) up in index_impl() but I might opt to avoid that dependency, since defaultdict is a bit subtle and relying on a given dict return value to actually be a defaultdict seems a bit hazardous unless clearly documented.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, indeed! We can concisely write the expression like that. And yes, lets use a normal dict since runs with no data map to empty lists. I kept the helper since we also use it within tags_impl so that route is consistent with the plugin being active.

Also, removed the duplicate comment.

name = 'tensorboard_text'
run_to_assets = self._multiplexer.PluginAssets(name)
for run, assets in run_to_assets.items():
if 'tensors.json' in assets:
tensors_json = self._multiplexer.RetrievePluginAsset(
run, name, 'tensors.json')
tensors = json.loads(tensors_json)
run_to_series[run] = tensors
run_to_series[run] += tensors
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we change these to += we probably want to do deduping, since I doubt we want duplicated tags if there are cases during the transition from legacy to new formats where the same tags were recorded in both places.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1, now, new-style summaries override old-style ones per prior behavior.

else:
run_to_series[run] = []
run_to_series[run] += []
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+= [] on a list has no effect, might as well just omit this whole else

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done - changed to = []. Added a comment.

@chihuahua chihuahua changed the title Make text plugin short-circuit Make text plugin's is_active method check for data in multiplexer first before perusing plugin assets. Mar 10, 2018
@chihuahua chihuahua changed the title Make text plugin's is_active method check for data in multiplexer first before perusing plugin assets. Make text plugin's is_active method check for data in multiplexer first before checking plugin assets. Mar 10, 2018
Copy link
Contributor

@nfelt nfelt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, but text_plugin_test.py is failing:

======================================================================
FAIL: testPluginIsActiveWhenTextRuns (__main__.TextPluginTest)
The plugin should be active when there are runs with text.
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/.bazel-output-base/bazel-sandbox/2750984358386572954/execroot/org_tensorflow_tensorboard/bazel-out/k8-fastbuild/bin/tensorboard/plugins/text/text_plugin_test.runfiles/org_tensorflow_tensorboard/tensorboard/plugins/text/text_plugin_test.py", line 372, in testPluginIsActiveWhenTextRuns
    self.assertIsActive(plugin, True)
  File "/home/travis/.bazel-output-base/bazel-sandbox/2750984358386572954/execroot/org_tensorflow_tensorboard/bazel-out/k8-fastbuild/bin/tensorboard/plugins/text/text_plugin_test.runfiles/org_tensorflow_tensorboard/tensorboard/plugins/text/text_plugin_test.py", line 336, in assertIsActive
    self.assertFalse(plugin.is_active())
AssertionError: True is not false

======================================================================
FAIL: testPluginTagsImpl (__main__.TextPluginTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/.bazel-output-base/bazel-sandbox/2750984358386572954/execroot/org_tensorflow_tensorboard/bazel-out/k8-fastbuild/bin/tensorboard/plugins/text/text_plugin_test.runfiles/org_tensorflow_tensorboard/tensorboard/plugins/text/text_plugin_test.py", line 391, in testPluginTagsImpl
    self.assertEqual({}, self.plugin.tags_impl())
AssertionError: {} != {'fry': [u'message', u'vector'], 'leela': [u'message', u'vector']}
- {}
+ {'fry': [u'message', u'vector'], 'leela': [u'message', u'vector']}

----------------------------------------------------------------------

@@ -234,9 +235,15 @@ def is_active(self):
if any(self._index_cached.values()):
return True

if bool(self._multiplexer.PluginRunToTagToContent(metadata.PLUGIN_NAME)):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having if bool(expr) is redundant - you can just do if expr.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

else:
run_to_series[run] += []
# The mapping should contain all runs among its keys.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, good catch. I feel like some plugins expect this (that index_impl() includes all runs, not just those with plugin data for that plugin) but not all of them? Do we have a set standard or is this just up to any plugin?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For all plugins, the "runs"/"tags" route should list all runs, not just those that include text summaries. Without this, the existing infrastructure breaks when it tries to look up non-plugin-specific runs in the run-to-tag mapping. There's a brief description within the internal change that removes the tf-sidebar-helper component.

for (run, tags) in mapping.items():
run_to_series[run] += tags.keys()
return run_to_series
mapping = six.iteritems(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: strictly speaking this isn't a mapping, it's an iterable of dict items - maybe rename to "items" or conversely, move the six.iteritems() call to inside the dict comprehension.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Modified tests to check for correct behavior when the plugin detects
relevant data within the multiplexer.

Specifically, in that case,

1. The thread that seeks plugin assets data should not start.
2. The plugin should be active despite how that thread had not started.
3. The tags route should respond with multiplexer data.
@chihuahua chihuahua merged commit 7f03e2a into tensorflow:master Mar 15, 2018
chihuahua added a commit to chihuahua/tensorboard that referenced this pull request Mar 27, 2018
Previously, text_plugin_test sometimes failed because tensorflow#1021 made the test check for complete dictionary equality, and tags may appear in different orders. This fix makes the test check for equality of content within lists, regardless of order. This makes the test parallel previous test logic for tags.
chihuahua added a commit that referenced this pull request Mar 27, 2018
Previously, text_plugin_test sometimes failed because #1021 made the test check for complete dictionary equality, and tags may appear in different orders for each test run. This fix makes the test check for equality of content within lists, regardless of order. This makes the test parallel previous test logic for tags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants