etcd3-py icon indicating copy to clipboard operation
etcd3-py copied to clipboard

setting a watch fails with AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'

Open pjz opened this issue 6 years ago • 12 comments

  • etcd3-py version: 0.1.6
  • Python version: 3.7
  • Operating System: linux

Description

I was trying to get a watch working in my app. It's currently complex, but if you have no idea why this is happening, I'll work on getting a stripped-down version working.

If it matters, I'm using an async client.

What I Did

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 283, in run
    for event in self:
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 356, in __iter__
    if not self._resp or self._resp.raw.closed:
AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 284, in run
    self.dispatch_event(event)
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 338, in __exit__
    self.stop()
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 295, in stop
    self._kill_response_stream()
  File "/tmp/xgw-venv/lib/python3.7/site-packages/etcd3/stateful/watch.py", line 260, in _kill_response_stream
    if not self._resp or (self._resp and self._resp.raw.closed):
AttributeError: 'ModelizedStreamResponse' object has no attribute 'raw'```

pjz avatar Jun 20 '19 19:06 pjz

async stateful util not supported, yet.

I opened a issuse https://github.com/Revolution1/etcd3-py/issues/16 long time ago, if you need this feature, I can try starting working on it.

Revolution1 avatar Jun 20 '19 19:06 Revolution1

Is there a watch feature that does support async? I can maybe use that instead.

pjz avatar Jun 20 '19 19:06 pjz

yes, you can use raw api client.watch_create instead

https://github.com/Revolution1/etcd3-py/blob/master/etcd3/stateful/watch.py#L386-L417

Revolution1 avatar Jun 20 '19 19:06 Revolution1

Hm. Given that I'm having difficulty understanding how it's all supposed to work, I should take you up on your offer to fix this feature for me. While you do that, I'll try and wrap my head around how the lower-level watch stuff works so I can maybe lend a hand.

pjz avatar Jun 20 '19 20:06 pjz

okay

Revolution1 avatar Jun 20 '19 20:06 Revolution1

Any progress on this?

pjz avatar Jul 08 '19 15:07 pjz

is there (failing) test code for this?

pjz avatar Jul 09 '19 15:07 pjz

Meanwhile, this is how async watch works for me (in case someone may still need it):

def get_range_end(prefix):
            return prefix[:-1] + chr(ord(prefix[-1]) + 1)

async def on_event(self, key, value, type):
           # your K/V event processing code here
           pass

async with etcd_client.watch_create(prefix, range_end=get_range_end(prefix)) as r:
            async for msg in r:
                log.info(msg)
                if msg.events:
                    for event in msg.events:
                        try:
                            await on_event(event.kv.key, event.kv.value, event.type)
                        except Exception as e:
                            log.exception(f'Failed to process event : {event}')

andr-c avatar Dec 18 '19 09:12 andr-c

This really should be in the documentation! The current docs give me absolutely no clue on how to use most of the async stuff.

agronholm avatar Feb 11 '20 05:02 agronholm

@andr-c It is not correct way because it block event loop and it is no way to stop watch for async client, so until the author adds full async features supports we have no way to async client + watcher.

Vasiliy566 avatar Feb 03 '23 10:02 Vasiliy566