jruizgit / rules

Durable Rules Engine
MIT License
1.14k stars 207 forks source link

Exception: Ruleset with {name of ruleset} already registered #262

Open lechiffre opened 4 years ago

lechiffre commented 4 years ago

Hi,

thanks for great module. I am trying to run in Python your "Hello world" example. I cannot run it more than once :(. Or I cannot run any other ruleset with different name. The exception is keep referring to the first run ruleset and any other rule I try to run does not work anymore and exception is keep referring to first rule set. See the exception below.

1) This is the response after I run the Hello world for the first time:

Hello World
{'sid': '0', 'id': 'sid-0', '$s': 1}

2) This is the exception I am getting after second run:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-2-bcb2fdd60e15> in <module>
      8         print('Hello {0}'.format(c.m.subject))
      9 
---> 10 post('test', { 'subject': 'World' })

~/anaconda3/lib/python3.7/site-packages/durable/lang.py in post(ruleset_name, message, complete)
    664 
    665 def post(ruleset_name, message, complete = None):
--> 666     return get_host().post(ruleset_name, message, complete)
    667 
    668 def post_batch(ruleset_name, messages, complete = None):

~/anaconda3/lib/python3.7/site-packages/durable/lang.py in get_host()
    659         ruleset_definitions[full_name] = ruleset_definition
    660 
--> 661     _main_host.register_rulesets(ruleset_definitions)
    662     _rulesets = {}
    663     return _main_host

~/anaconda3/lib/python3.7/site-packages/durable/engine.py in register_rulesets(self, ruleset_definitions)
    784         for ruleset_name, ruleset in rulesets.items():
    785             if ruleset_name in self._ruleset_directory:
--> 786                 raise Exception('Ruleset with name {0} already registered'.format(ruleset_name))
    787             else:
    788                 self._ruleset_directory[ruleset_name] = ruleset

Exception: Ruleset with name test already registered

Any ideas what can I do with that? Thanks a million

jruizgit commented 4 years ago

Hi, thanks for asking the question. Would you mind pasting the exception that led to the exception?

lechiffre commented 4 years ago

Hi, yes. If I run the code below in jupiter notebook snippet twice, the exception above will raise. After that any other ruleset I would run would still return the exactly same exception as described above.

Here is what I run:

from durable.lang import *

with ruleset('test'):
    # antecedent
    @when_all(m.subject == 'World')
    def say_hello(c):
        # consequent
        print('Hello {0}'.format(c.m.subject))

post('test', { 'subject': 'World' })

Thanks for getting back to me.

lechiffre commented 4 years ago

Is it possible that this is an error that appears only in Jupyte notebook?

jruizgit commented 4 years ago

Hi, I'm guessing the notebook is running the code in the same python process. Two rulesets with the same name cannot exist in the same process. If you want to try a different ruleset, I suggest you use a different name. If you want to try the same ruleset, you don't need to declare it again. You just need to post events and assert facts.

staylorx commented 4 years ago

I've had the same experience. Not an error, per se, and your explanation above is clear. However, to allow for some idempotence, is there a way to reset the rules engine in code? If you've already got a way to clear rulesets, I just couldn't find it in the docs easily. So, apologies if you've already done this.

Duplicating the copy from above but with an imagined clear or reset:

from durable.lang import *

#I would expect this to clear the ruleset and return successfully even if the ruleset is already clear or doesn't exist:
ruleset('test').clear()  # or .reset() 

# then all should move along succesfully
with ruleset('test'):
    @when_all(m.subject == 'World')
    def say_hello(c):
        print ('Hello {0}'.format(c.m.subject))

post('test', { 'subject': 'World' })
PrashanthK23 commented 4 years ago

Hi @staylorx did you find any solution for reset/clear ? I have a business need to do that

PrashanthK23 commented 4 years ago

Hi @jruizgit,
1) Can we able to clear/reset the ruleset (as I want to update the ruleset regularly by maintaining the same ruleset name) 2) Do we have any method to check a ruleset is already exists or not ?

jadami10 commented 4 years ago

For those looking for an easy way to test this in a notebook, you can clear the ruleset directory before recreating the rule. I use this to keep altering the say_hello function and just rerun the cell.

from durable.lang import ruleset, when_all, m, post, _main_host

if _main_host is not None:
    _main_host._ruleset_directory.clear()

with ruleset('test'):
    @when_all(m.subject == 'World')
    def say_hello(c):
        print ('Hello {0}'.format(c.m.subject))

You could also use that same method to check if rules exist already. I'd be happy to contribute a change to allow querying and overriding the _ruleset_directory if @jruizgit wants that functionality.

jruizgit commented 4 years ago

Hi, thanks for the suggestion. I'm sorry I missed this comment a while back. Please feel free to send me a pull request. Otherwise I'm planning to add the functionality in the next couple of weeks.

harsha20-creator commented 2 years ago

@jruizgit wanted to check on the above on how to clear the rule if that has already been run. I have a rule and when that rule triggers within few seconds when i trigger the same rule with different request. i get the above error.

I was trying to do something above but _ruleset_directory being a protected variable is not exposed to us. Appreciate if you can provide some insight on this one.

I tried something like this

if get_host() is not None and get_host().get_ruleset("test") is not None: get_host().get_ruleset("test").clear()

but still i wasn't able to get this cleared and ran into this error 'Exception: Ruleset with name test already registered\n

ChristopherCorvo commented 2 years ago

@jruizgit Also checking to see if the feature to update or clear an established rule has been created. I see that you were talking about developing this feature back in 2020. Curious if it was created or if there is a reason for why this feature should not be used. Thanks

alifim commented 3 months ago

I've managed to do it by adding this before creating ruleset. basically, it removes the ruleset from the ruleset dictionary

from durable.lang import ruleset, when_all, m, post, get_host

ruleset_name = "test"
host = get_host()

if ruleset_name in host._ruleset_directory.keys():
        host._ruleset_directory.pop(ruleset_name, None)

with ruleset(ruleset_name):
    ...