Comments (2)
Hi @jonathan-dev thank you for submitting this issue;
I've modified your example slightly as below, I do believe it achieves the same:
def test_issue_694_fail():
import time
from datetime import timedelta
from reactivex import operators as ops
from reactivex.subject import Subject
su = Subject()
v = 0
def set_checker(x):
nonlocal v
v = x
def wait_a_while(*_):
time.sleep(10 / 1000) # <-- the "10" here will be roughly how many subject emissions are missed
su.pipe(
ops.window_with_time_or_count(
count=1_000, timespan=timedelta(milliseconds=1_000)
),
ops.flat_map(
lambda window: window.pipe(
ops.count(),
)
),
ops.do_action(wait_a_while), # <-- cause a delay when a window completes and `count` emits on_next
ops.scan(lambda acc, x: acc + x, 0), # <-- use scan for easier check of what I think you meant when you said "sums to 1999 or 2000"
).subscribe(on_next=set_checker)
for i in range(2000):
time.sleep(1 / 1000)
su.on_next(i)
time.sleep(2)
assert v == 2_000 # <-- will fail with something like 1980 != 2000 ; since we sleep 10 ticks two times, 20 are missing
The "section" you commented out in your code is replaced with wait_a_while
because that's what causes the problem: the computation time makes the window miss emissions.
This only happens for a window that is closed due to time (not count) because that is happening on a separate thread - whereas for count, it's on the same thread. So while the window is being closed by s.on_completed()
in the create_timer window, the main thread continues to emit and that's not caught by the next window.
I do not feel that this is a bug, but a threading issue. Happy to hear your thoughts.
Below is a version using a lock which I believe works, though it might not be suitable for your use case:
def test_issue_694():
import time
from datetime import timedelta
from reactivex import operators as ops
from reactivex.subject import Subject
su = Subject()
lock = threading.Lock()
v = 0
def set_checker(x):
nonlocal v
v = x
lock.release() # <-- unlock only at the very end of the function executions caused by window's on_completed() call
def wait_a_while(*_):
time.sleep(10 / 1000)
su.pipe(
ops.window_with_time_or_count(
count=1_000, timespan=timedelta(milliseconds=1_000)
),
ops.flat_map(
lambda window: window.pipe(
ops.do_action(on_completed=lock.acquire), # <-- lock as soon as window is completed
ops.count(),
)
),
ops.do_action(wait_a_while),
ops.scan(lambda acc, x: acc + x, 0),
# end section
).subscribe(on_next=set_checker)
for i in range(2000):
time.sleep(1 / 1000)
while lock.locked():
pass # <-- wait until the lock is released on the other thread
su.on_next(i)
time.sleep(2)
assert v == 2_000
Hope this helps!
from rxpy.
Hi there, just as a follow up, your case got me diving a bit more into schedulers; I believe that using an EventLoopScheduler
would likely be the right way: the version below also works:
def test_issue_694_event_loop():
import time
from datetime import timedelta
from reactivex import operators as ops
from reactivex.subject import Subject
from reactivex.scheduler import EventLoopScheduler
su = Subject()
event_loop = EventLoopScheduler()
v = 0
def set_checker(x):
nonlocal v
v = x
def wait_a_while(*_):
time.sleep(10 / 1000)
su.pipe(
ops.window_with_time_or_count(
count=1_000, timespan=timedelta(milliseconds=1_000)
),
ops.flat_map(
lambda window: window.pipe(
ops.observe_on(event_loop), # <- event loop
ops.count(),
)
),
ops.do_action(wait_a_while),
ops.scan(lambda acc, x: acc + x, 0),
# end section
).subscribe(on_next=set_checker)
for i in range(2000):
time.sleep(1 / 1000)
su.on_next(i)
time.sleep(2)
assert v == 2_000
Simply commenting out the ops.observer_on
line shows the initial issue again.
from rxpy.
Related Issues (20)
- [Question] shiping data between asyncio and rxpy HOT 1
- [Question] Reading/writing from/to a Pandas DataFrame in rxpy HOT 2
- [TESTING] Notification equality uses string representation HOT 2
- Cannot pickle reactive classes
- Zip operator does not work HOT 3
- Rolling throttle operator
- reactivex.timer emits immediately on second subscription HOT 1
- Unexpected results of switch_map operator HOT 1
- Verson number in GitHub release is 0.0.0
- [BUG] buffer_with_time_or_count lost some data HOT 1
- [BUG] buffer_with_time_or_count loses data
- Python 3.12 deprecates timezone non aware utcfromtimestamp() and utcnow()
- This is a concurrent library, but not thread safe?
- AsyncIOScheduler.schedule is not thread safe!
- RxPY/ example / timer.py broken: Future is not iterable
- switch_map() operator not listed in documentation
- `operators.retry(n)` interferes with non-erroring repeats
- Concurrent Execution Not Working as Expected with RxPY ThreadPoolScheduler HOT 1
- Questions about Copilot + Open Source Software Hierarchy
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rxpy.