errbotio / errbot

Errbot is a chatbot, a daemon that connects to your favorite chat service and bring your tools and some fun into the conversation.
http://errbot.io
GNU General Public License v3.0
3.13k stars 615 forks source link

Circular Dependencies when there are none #1397

Closed jakubclark closed 2 years ago

jakubclark commented 4 years ago

I am...

I am running...

Issue description

I have a situation where I have a total of 3 plugins:

Below are their plugin dependencies:

I've roughly visualized the dependencies here:

deps

Trying to run with this configuration results in an error:

2019-12-05 20:21:59,078 INFO     errbot.core               Error: PluginA failed to activate: Circular dependency in the set of plugins (PluginC, PluginA, PluginB).

PluginA fails to load, due to "circular dependencies". However, I do not see circular dependencies from what I described above.

So is this intentional; not allowing PluginA to depend on PluginC, since PluginB already depends on PluginC, and PluginA does depend on PluginB?

There aren't circular dependencies, since self depends on the same plugins as a child plugin depends on.

A workaround is to do something like this:

PluginA does not depend on PluginC

Then, from within PluginA do teh following:

self.get_plugin('PluginB').get_plugin('PluginC')

Steps to reproduce

I've created a repo with the necessary code to reproduce this error here. Simply run the test: pytest plugins_test.py. Or run errbot itself, it is configured for text mode.

sijis commented 4 years ago

I have not run this but my guess is to remove PluginA to depend on PluginC.

You should be able to load up pluginC from pluginA, as self.get_plugin('PluginC').

jakubclark commented 4 years ago

Thanks @sijis. Removing the PluginC depedency from PluginA seems to work, I'll try this against my actual chatbot tomorrow. If all goes well, I'll close this issue.

jakubclark commented 4 years ago

By making PluginA not explicitly depend on PluginC the "circular dependencies" have been resolved, as PluginB already depends on PluginC.

HandsomeWins commented 4 years ago

Hi, I have the exact same sort of setup as @jakubclark and the suggested mitigations don't work for me. Agree with @jakubclark that this shouldn't be a circular dependency issue.

I've also run into another issue while trying to set up a simple PluginA -> PluginB -> PluginC relationship: for some reason, despite PluginB's Core section listing PluginC as a dependency, self.dependencies for PluginB doesn't list PluginC as a dependency.. so when I try self.get_plugin('PluginC') in PluginB I get an exception about how Plugin dependency PluginC needs to be listed in section [Core] key "DependsOn" to be used in get_plugin.

It doesn't sound like this issue is closed. The circular dependency logic seems faulty and there's some sort of bug that results in self.dependencies not being populated properly.

EDIT: Added self.dependencies.append('PluginC') in PluginB before self.get_plugin('PluginC'), everything works fine. Seems like a bug?

jakubclark commented 4 years ago

Reopening this, as the issue has occurred once again:

PluginA depends on PluginB PluginB depends on PluginC

class PluginA(BotPlugin)
    def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.plugin_c = self.get_plugin('PluginC')

Error message: "Plugin dependency PluginC needs to be listed in section [Core] key "DependsOn" to be used in get_plugin."

I had to restart my bot 3 times, before self.get_plugin('PluginC') did not fail.

It seems that it is random, if self.get_plugin('PluginC') results in an error. If it does result in an error, the bot must be restarted a few times, and eventually it will work.

sijis commented 4 years ago

Could you validate if this behavior happens using the master branch?

in-op commented 4 years ago

I can confirm this happens with Errbot version 6.1.4. Inconsistently giving me the same error.