@@ -481,9 +481,8 @@ func (o *ObservableImpl) BufferWithTime(timespan Duration, opts ...Option) Obser
481
481
if item .Error () {
482
482
next <- item
483
483
return
484
- } else {
485
- buffer = append (buffer , item .V )
486
484
}
485
+ buffer = append (buffer , item .V )
487
486
case <- time .After (timespan .duration ()):
488
487
if len (buffer ) != 0 {
489
488
select {
@@ -542,16 +541,15 @@ func (o *ObservableImpl) BufferWithTimeOrCount(timespan Duration, count int, opt
542
541
if item .Error () {
543
542
next <- item
544
543
return
545
- } else {
546
- buffer = append (buffer , item .V )
547
- if len (buffer ) == count {
548
- select {
549
- case <- ctx .Done ():
550
- return
551
- case next <- Of (buffer ):
552
- }
553
- buffer = make ([]interface {}, 0 )
544
+ }
545
+ buffer = append (buffer , item .V )
546
+ if len (buffer ) == count {
547
+ select {
548
+ case <- ctx .Done ():
549
+ return
550
+ case next <- Of (buffer ):
554
551
}
552
+ buffer = make ([]interface {}, 0 )
555
553
}
556
554
case <- time .After (timespan .duration ()):
557
555
if len (buffer ) != 0 {
@@ -2501,65 +2499,158 @@ func (op *windowWithCountOperator) end(_ context.Context, _ chan<- Item) {
2501
2499
func (op * windowWithCountOperator ) gatherNext (_ context.Context , _ Item , _ chan <- Item , _ operatorOptions ) {
2502
2500
}
2503
2501
2502
+ // WindowWithTime periodically subdivides items from an Observable into Observables based on timed windows
2503
+ // and emit them rather than emitting the items one at a time.
2504
2504
func (o * ObservableImpl ) WindowWithTime (timespan Duration , opts ... Option ) Observable {
2505
2505
if timespan == nil {
2506
2506
return Thrown (IllegalInputError {error : "timespan must no be nil" })
2507
2507
}
2508
2508
2509
- //option := parseOptions(opts...)
2509
+ f := func (ctx context.Context , next chan Item , option Option , opts ... Option ) {
2510
+ defer close (next )
2511
+ observe := o .Observe (opts ... )
2512
+ ch := option .buildChannel ()
2513
+ empty := true
2514
+ if ! Of (FromChannel (ch )).SendWithContext (ctx , next ) {
2515
+ return
2516
+ }
2517
+
2518
+ for {
2519
+ select {
2520
+ case <- ctx .Done ():
2521
+ close (ch )
2522
+ return
2523
+ case item , ok := <- observe :
2524
+ if ! ok {
2525
+ close (ch )
2526
+ return
2527
+ }
2528
+ if item .Error () {
2529
+ if ! item .SendWithContext (ctx , ch ) {
2530
+ return
2531
+ }
2532
+ if option .getErrorStrategy () == Stop {
2533
+ close (ch )
2534
+ return
2535
+ }
2536
+ }
2537
+ if ! item .SendWithContext (ctx , ch ) {
2538
+ return
2539
+ }
2540
+ empty = false
2541
+ case <- time .After (timespan .duration ()):
2542
+ if empty {
2543
+ continue
2544
+ }
2545
+ close (ch )
2546
+ ch = option .buildChannel ()
2547
+ empty = true
2548
+ if ! Of (FromChannel (ch )).SendWithContext (ctx , next ) {
2549
+ return
2550
+ }
2551
+ }
2552
+ }
2553
+ }
2554
+
2555
+ option := parseOptions (opts ... )
2556
+
2557
+ if option .isEagerObservation () {
2558
+ next := option .buildChannel ()
2559
+ ctx := option .buildContext ()
2560
+ go f (ctx , next , option , opts ... )
2561
+ return & ObservableImpl {iterable : newChannelIterable (next )}
2562
+ }
2510
2563
2511
- // TODO Handle eager observation
2512
2564
return & ObservableImpl {
2513
2565
iterable : newFactoryIterable (func (propagatedOptions ... Option ) <- chan Item {
2514
2566
mergedOptions := append (opts , propagatedOptions ... )
2515
2567
option := parseOptions (mergedOptions ... )
2516
2568
next := option .buildChannel ()
2517
2569
ctx := option .buildContext ()
2570
+ go f (ctx , next , option , mergedOptions ... )
2571
+ return next
2572
+ }),
2573
+ }
2574
+ }
2518
2575
2519
- go func () {
2520
- defer close (next )
2521
- observe := o .Observe (mergedOptions ... )
2522
- ch := option .buildChannel ()
2523
- empty := true
2524
- select {
2525
- case <- ctx .Done ():
2576
+ func (o * ObservableImpl ) WindowWithTimeOrCount (timespan Duration , count int , opts ... Option ) Observable {
2577
+ if timespan == nil {
2578
+ return Thrown (IllegalInputError {error : "timespan must no be nil" })
2579
+ }
2580
+ if count < 0 {
2581
+ return Thrown (IllegalInputError {error : "count must be positive or nil" })
2582
+ }
2583
+
2584
+ f := func (ctx context.Context , next chan Item , option Option , opts ... Option ) {
2585
+ defer close (next )
2586
+ observe := o .Observe (opts ... )
2587
+ ch := option .buildChannel ()
2588
+ iCount := 0
2589
+ if ! Of (FromChannel (ch )).SendWithContext (ctx , next ) {
2590
+ return
2591
+ }
2592
+
2593
+ for {
2594
+ select {
2595
+ case <- ctx .Done ():
2596
+ close (ch )
2597
+ return
2598
+ case item , ok := <- observe :
2599
+ if ! ok {
2600
+ close (ch )
2526
2601
return
2527
- case next <- Of (FromChannel (ch )):
2528
2602
}
2529
-
2530
- for {
2531
- select {
2532
- case <- ctx .Done ():
2603
+ if item .Error () {
2604
+ if ! item .SendWithContext (ctx , ch ) {
2533
2605
return
2534
- case item , ok := <- observe :
2535
- if ! ok {
2536
- close (ch )
2537
- return
2538
- }
2539
- if item .Error () {
2540
- ch <- item
2541
- close (ch )
2542
- return
2543
- } else {
2544
- ch <- item
2545
- empty = false
2546
- }
2547
- case <- time .After (timespan .duration ()):
2548
- if empty {
2549
- continue
2550
- }
2606
+ }
2607
+ if option .getErrorStrategy () == Stop {
2551
2608
close (ch )
2552
- ch = option .buildChannel ()
2553
- empty = true
2554
- select {
2555
- case <- ctx .Done ():
2556
- return
2557
- case next <- Of (FromChannel (ch )):
2558
- }
2609
+ return
2559
2610
}
2560
2611
}
2561
- }()
2612
+ if ! item .SendWithContext (ctx , ch ) {
2613
+ return
2614
+ }
2615
+ iCount ++
2616
+ if iCount == count {
2617
+ close (ch )
2618
+ ch = option .buildChannel ()
2619
+ iCount = 0
2620
+ if ! Of (FromChannel (ch )).SendWithContext (ctx , next ) {
2621
+ return
2622
+ }
2623
+ }
2624
+ case <- time .After (timespan .duration ()):
2625
+ if iCount == 0 {
2626
+ continue
2627
+ }
2628
+ close (ch )
2629
+ ch = option .buildChannel ()
2630
+ iCount = 0
2631
+ if ! Of (FromChannel (ch )).SendWithContext (ctx , next ) {
2632
+ return
2633
+ }
2634
+ }
2635
+ }
2636
+ }
2637
+
2638
+ option := parseOptions (opts ... )
2639
+
2640
+ if option .isEagerObservation () {
2641
+ next := option .buildChannel ()
2642
+ ctx := option .buildContext ()
2643
+ go f (ctx , next , option , opts ... )
2644
+ return & ObservableImpl {iterable : newChannelIterable (next )}
2645
+ }
2562
2646
2647
+ return & ObservableImpl {
2648
+ iterable : newFactoryIterable (func (propagatedOptions ... Option ) <- chan Item {
2649
+ mergedOptions := append (opts , propagatedOptions ... )
2650
+ option := parseOptions (mergedOptions ... )
2651
+ next := option .buildChannel ()
2652
+ ctx := option .buildContext ()
2653
+ go f (ctx , next , option , mergedOptions ... )
2563
2654
return next
2564
2655
}),
2565
2656
}
0 commit comments