-
Notifications
You must be signed in to change notification settings - Fork 567
expose libuv uv_fs_event functionality #474
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
Merged
Merged
Changes from all commits
Commits
Show all changes
18 commits
Select commit
Hold shift + click to select a range
0d514b5
first set of changes
44b9d3e
finished testing functionality of fs_events
93fa1b3
remove file I was using for testing
9fb994c
correct formatting etc
39b2fed
newer Python versions do not have asyncio.events._TransProtPair, defi…
jensbjorgensen 2aaa9a6
Merge remote-tracking branch 'magicstack/master'
jensbjorgensen 950d8be
various changes per maintainer following review
jensbjorgensen 97aabcf
dang, forgot test_sourcecode.py... fixed
jensbjorgensen de85d80
recursive param in test should be boolean, not 0
jensbjorgensen 48f3a26
move function to get underlying loop pointer outside the object, expo…
jensbjorgensen 4c20dd9
since type is assumed int, can certainly be negative
jensbjorgensen 55d5ec9
fix indentation
jensbjorgensen 6807674
Merge branch 'master' into master
fantix 33296bf
Fix fs_event implementation
fantix 91def83
Allow both RENAME and CHANGE
fantix 9148731
Merge branch 'master' into master
fantix fe77faa
CRF: optimize tests
fantix 5658110
Update pyOpenSSL to 22.x
fantix File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import asyncio | ||
import os.path | ||
import tempfile | ||
|
||
from uvloop import _testbase as tb | ||
from uvloop.loop import FileSystemEvent | ||
|
||
|
||
class Test_UV_FS_EVENT_CHANGE(tb.UVTestCase): | ||
async def _file_writer(self): | ||
f = await self.q.get() | ||
while True: | ||
f.write('hello uvloop\n') | ||
f.flush() | ||
x = await self.q.get() | ||
if x is None: | ||
return | ||
|
||
def fs_event_setup(self): | ||
self.change_event_count = 0 | ||
self.fname = '' | ||
self.q = asyncio.Queue() | ||
|
||
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent): | ||
_d, fn = os.path.split(self.fname) | ||
self.assertEqual(ev_fname, fn) | ||
self.assertEqual(evt, FileSystemEvent.CHANGE) | ||
self.change_event_count += 1 | ||
if self.change_event_count < 4: | ||
self.q.put_nowait(0) | ||
else: | ||
self.q.put_nowait(None) | ||
|
||
def test_fs_event_change(self): | ||
self.fs_event_setup() | ||
|
||
async def run(write_task): | ||
self.q.put_nowait(tf) | ||
try: | ||
await asyncio.wait_for(write_task, 4) | ||
except asyncio.TimeoutError: | ||
write_task.cancel() | ||
|
||
with tempfile.NamedTemporaryFile('wt') as tf: | ||
self.fname = tf.name.encode() | ||
h = self.loop._monitor_fs(tf.name, self.event_cb) | ||
self.assertFalse(h.cancelled()) | ||
|
||
self.loop.run_until_complete(run( | ||
self.loop.create_task(self._file_writer()))) | ||
h.cancel() | ||
self.assertTrue(h.cancelled()) | ||
|
||
self.assertEqual(self.change_event_count, 4) | ||
|
||
|
||
class Test_UV_FS_EVENT_RENAME(tb.UVTestCase): | ||
async def _file_renamer(self): | ||
await self.q.get() | ||
os.rename(os.path.join(self.dname, self.changed_name), | ||
os.path.join(self.dname, self.changed_name + "-new")) | ||
await self.q.get() | ||
|
||
def fs_event_setup(self): | ||
self.dname = '' | ||
self.changed_name = "hello_fs_event.txt" | ||
self.changed_set = {self.changed_name, self.changed_name + '-new'} | ||
self.q = asyncio.Queue() | ||
|
||
def event_cb(self, ev_fname: bytes, evt: FileSystemEvent): | ||
ev_fname = ev_fname.decode() | ||
self.assertEqual(evt, FileSystemEvent.RENAME) | ||
self.changed_set.remove(ev_fname) | ||
if len(self.changed_set) == 0: | ||
self.q.put_nowait(None) | ||
|
||
def test_fs_event_rename(self): | ||
self.fs_event_setup() | ||
|
||
async def run(write_task): | ||
self.q.put_nowait(0) | ||
try: | ||
await asyncio.wait_for(write_task, 4) | ||
except asyncio.TimeoutError: | ||
write_task.cancel() | ||
|
||
with tempfile.TemporaryDirectory() as td_name: | ||
self.dname = td_name | ||
f = open(os.path.join(td_name, self.changed_name), 'wt') | ||
f.write('hello!') | ||
f.close() | ||
h = self.loop._monitor_fs(td_name, self.event_cb) | ||
self.assertFalse(h.cancelled()) | ||
|
||
self.loop.run_until_complete(run( | ||
self.loop.create_task(self._file_renamer()))) | ||
h.cancel() | ||
self.assertTrue(h.cancelled()) | ||
|
||
self.assertEqual(len(self.changed_set), 0) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
cdef class UVFSEvent(UVHandle): | ||
cdef: | ||
object callback | ||
bint running | ||
|
||
cdef _init(self, Loop loop, object callback, object context) | ||
cdef _close(self) | ||
cdef start(self, char* path, int flags) | ||
cdef stop(self) | ||
|
||
@staticmethod | ||
cdef UVFSEvent new(Loop loop, object callback, object context) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import enum | ||
|
||
|
||
class FileSystemEvent(enum.IntEnum): | ||
RENAME = uv.UV_RENAME | ||
CHANGE = uv.UV_CHANGE | ||
RENAME_CHANGE = RENAME | CHANGE | ||
|
||
|
||
@cython.no_gc_clear | ||
cdef class UVFSEvent(UVHandle): | ||
cdef _init(self, Loop loop, object callback, object context): | ||
cdef int err | ||
|
||
self._start_init(loop) | ||
|
||
self._handle = <uv.uv_handle_t*>PyMem_RawMalloc( | ||
sizeof(uv.uv_fs_event_t) | ||
) | ||
if self._handle is NULL: | ||
self._abort_init() | ||
raise MemoryError() | ||
|
||
err = uv.uv_fs_event_init( | ||
self._loop.uvloop, <uv.uv_fs_event_t*>self._handle | ||
) | ||
if err < 0: | ||
self._abort_init() | ||
raise convert_error(err) | ||
|
||
self._finish_init() | ||
|
||
self.running = 0 | ||
self.callback = callback | ||
if context is None: | ||
context = Context_CopyCurrent() | ||
self.context = context | ||
|
||
cdef start(self, char* path, int flags): | ||
cdef int err | ||
|
||
self._ensure_alive() | ||
|
||
if self.running == 0: | ||
err = uv.uv_fs_event_start( | ||
<uv.uv_fs_event_t*>self._handle, | ||
__uvfsevent_callback, | ||
path, | ||
flags, | ||
) | ||
if err < 0: | ||
exc = convert_error(err) | ||
self._fatal_error(exc, True) | ||
return | ||
self.running = 1 | ||
|
||
cdef stop(self): | ||
cdef int err | ||
|
||
if not self._is_alive(): | ||
self.running = 0 | ||
return | ||
|
||
if self.running == 1: | ||
err = uv.uv_fs_event_stop(<uv.uv_fs_event_t*>self._handle) | ||
self.running = 0 | ||
if err < 0: | ||
exc = convert_error(err) | ||
self._fatal_error(exc, True) | ||
return | ||
|
||
cdef _close(self): | ||
try: | ||
self.stop() | ||
finally: | ||
UVHandle._close(<UVHandle>self) | ||
|
||
def cancel(self): | ||
self._close() | ||
|
||
def cancelled(self): | ||
return self.running == 0 | ||
|
||
@staticmethod | ||
cdef UVFSEvent new(Loop loop, object callback, object context): | ||
cdef UVFSEvent handle | ||
handle = UVFSEvent.__new__(UVFSEvent) | ||
handle._init(loop, callback, context) | ||
return handle | ||
|
||
|
||
cdef void __uvfsevent_callback(uv.uv_fs_event_t* handle, const char *filename, | ||
int events, int status) with gil: | ||
if __ensure_handle_data( | ||
<uv.uv_handle_t*>handle, "UVFSEvent callback" | ||
) == 0: | ||
return | ||
|
||
cdef: | ||
UVFSEvent fs_event = <UVFSEvent> handle.data | ||
Handle h | ||
|
||
try: | ||
h = new_Handle( | ||
fs_event._loop, | ||
fs_event.callback, | ||
(filename, FileSystemEvent(events)), | ||
fs_event.context, | ||
) | ||
h._run() | ||
except BaseException as ex: | ||
fs_event._error(ex, False) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.