Serialize forces an Observable to make serialized calls and to be well-behaved.
(from int, identifier func(interface{}) int, opts ...Option)
| 2077 | |
| 2078 | // Serialize forces an Observable to make serialized calls and to be well-behaved. |
| 2079 | func (o *ObservableImpl) Serialize(from int, identifier func(interface{}) int, opts ...Option) Observable { |
| 2080 | option := parseOptions(opts...) |
| 2081 | next := option.buildChannel() |
| 2082 | |
| 2083 | ctx := option.buildContext(o.parent) |
| 2084 | minHeap := binaryheap.NewWith(func(a, b interface{}) int { |
| 2085 | return a.(int) - b.(int) |
| 2086 | }) |
| 2087 | counter := int64(from) |
| 2088 | items := make(map[int]interface{}) |
| 2089 | |
| 2090 | go func() { |
| 2091 | src := o.Observe(opts...) |
| 2092 | defer close(next) |
| 2093 | |
| 2094 | for { |
| 2095 | select { |
| 2096 | case <-ctx.Done(): |
| 2097 | return |
| 2098 | case item, ok := <-src: |
| 2099 | if !ok { |
| 2100 | return |
| 2101 | } |
| 2102 | if item.Error() { |
| 2103 | next <- item |
| 2104 | return |
| 2105 | } |
| 2106 | |
| 2107 | id := identifier(item.V) |
| 2108 | minHeap.Push(id) |
| 2109 | items[id] = item.V |
| 2110 | |
| 2111 | for !minHeap.Empty() { |
| 2112 | v, _ := minHeap.Peek() |
| 2113 | id := v.(int) |
| 2114 | if atomic.LoadInt64(&counter) == int64(id) { |
| 2115 | if itemValue, contains := items[id]; contains { |
| 2116 | minHeap.Pop() |
| 2117 | delete(items, id) |
| 2118 | Of(itemValue).SendContext(ctx, next) |
| 2119 | counter++ |
| 2120 | continue |
| 2121 | } |
| 2122 | } |
| 2123 | break |
| 2124 | } |
| 2125 | } |
| 2126 | } |
| 2127 | }() |
| 2128 | |
| 2129 | return &ObservableImpl{ |
| 2130 | iterable: newChannelIterable(next), |
| 2131 | } |
| 2132 | } |
| 2133 | |
| 2134 | // Skip suppresses the first n items in the original Observable and |
| 2135 | // returns a new Observable with the rest items. |
nothing calls this directly
no test coverage detected