Git Product home page Git Product logo

Comments (15)

aleneum avatar aleneum commented on June 19, 2024 1

In acbcdae I added special treatment for curio CancelScopes. I also added a test to check whether this treatment might cause callbacks to cancel themselves when they transititon to another state. It passes for now.

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024 1

just fyi: 0.8.5 has been released

from transitions-anyio.

thedrow avatar thedrow commented on June 19, 2024

@aleneum If you don't mind, please take a look.

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

It seems like cancel_soon isn't actually cancelled when the scope is.

import anyio
from anyio import create_task_group, get_cancelled_exc_class, open_cancel_scope


async def cancel_soon():
    await anyio.sleep(1)
    raise TimeoutError("Callback was not cancelled!")


async def call_delayed(func, time):
    await anyio.sleep(time)
    await func()


async def main():
    async with create_task_group() as tg:
        async with open_cancel_scope(shield=False) as scope:
            await tg.spawn(cancel_soon)
            await tg.spawn(call_delayed, scope.cancel, 0.1)

anyio.run(main)

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

Okay, so open_cancel_scope must prepend create_task_group or the cancel scope of tg has to be directly used:

works:

async def main():
    async with open_cancel_scope(shield=False) as scope:
        async with create_task_group() as tg:
            await tg.spawn(cancel_soon)
            await tg.spawn(call_delayed, scope.cancel, 0.1)

also works:

async def main():
    async with create_task_group() as tg:
        await tg.spawn(cancel_soon)
        await tg.spawn(call_delayed, tg.cancel_scope.cancel, 0.1)

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

If cancel_soon is rewritten into:

async def cancel_soon():
    try:
        await anyio.sleep(1)
        raise TimeoutError("Callback was not cancelled!")
    except get_cancelled_exc_class():
        print("Cancel soon was cancelled")
        raise

the cancellation messages is shown but the TimeoutError is raised anyway 😕

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

I guess some of the weirdness is due to the fact that CancelScope.cancel needs to be awaited while an asyncio.Task can be cancelled synchronously. However, even if I await scope.cancel, things dont work. I added some print to switch_model_context and process_context and ran test_multiple_models:

current scope is <anyio._backends._asyncio.CancelScope object at 0x7f67efff53c0>
cancel scope <anyio._backends._asyncio.CancelScope object at 0x7f67f012bbc0>
scope <anyio._backends._asyncio.CancelScope object at 0x7f67efff53c0> was cancelled

transitions attempts to cancel the correct scope (0x7f67f012bbc0) but the scope that exits is the CURRENT scope (0x7f67efff53c0). Shielding does not help and reraising the cancel event does not help either.

changes:

    async def process_context(self, func, model):
        if self.current_context.get() is None:
            try:
                async with open_cancel_scope(shield=False) as scope:
                    self.current_context.set(scope)
                    return await func()
            except get_cancelled_exc_class():
                print(f"scope {scope} was cancelled")
                return False
        return await func()

    async def switch_model_context(self, model):
        current_scope = self.current_context.get()
        running_scope = self.async_tasks.get(model, None)
        if current_scope != running_scope:
            self.async_tasks[model] = self.current_context.get()
            if running_scope is not None:
                print(f"current scope is {current_scope}")
                print(f"cancel scope {running_scope}")
                await running_scope.cancel()

from transitions-anyio.

thedrow avatar thedrow commented on June 19, 2024

So how do we get the correct scope?

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

it seems that open_cancel_scope does not raise an exception when its cancelled. I dont know enough about anyio internals to get why this is the case. This can be fixed quite easily as seen in d1903c3. However (and that took waaaay longer that it should), it seems that depending on the backend tasks might not been cancelled appropriately. The 'fix' above works for asyncio and trio but not curio

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

for queing to work. tasks need to be passed to (Async)Machine._process. That has been fixed as well.

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

oh, remark. for this to work AsyncMachine has to be tweaked. switch_model_context needs to be awaited.

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

I applied that change to transitions master (See here).

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

I added the changes that were made in transitions to deal with more complex task configurations (protected_tasks) and clean up after a trigger has been processed to prevent memory leaks when many (as in thousands) models are used.

from transitions-anyio.

aleneum avatar aleneum commented on June 19, 2024

So, for curio the 'problem' is, that spawned tasks seem to run in the same context.

from transitions-anyio.

thedrow avatar thedrow commented on June 19, 2024

Wonderful!
I'll wait for a new release before releasing this library.
Please ping me when you do so.

from transitions-anyio.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.