You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
addresses bugs and add assertions to verify correctness:
- no internal fifo buffer overflows
- the ordering invariant is maintained, such
that the consumer consumes, in sequential
order, the complete set of products produced.
Once `producer-consumer` has been compiled, in the same directory as this README file run `./producer-consumer`. You should a set of messages from: Main, Buffer, Producer, and Consumer actors.
107
+
Once `producer-consumer` has been compiled, in the same directory as this README file run `./producer-consumer`. You should a see of a log like:
27
108
28
109
```console
29
110
$ ./producer-consumer
30
-
**Main** Finished.
31
-
**Buffer** Permission_to_produce
32
-
**Buffer** Permission_to_produce: Calling producer to produce
33
-
...
34
-
**Buffer** Store_product
35
-
**Buffer** Store_product: Calling consumer to consume
36
-
**Consumer** Consuming product 2
111
+
test: fifo/basic apply() called.
112
+
1 test started, 0 complete: fifo/basic started
113
+
fifo: created with capacity: 2 and size: 2
114
+
consumer: started. _next = 0
115
+
producer: created. will produce 3
116
+
fifo: consumerRequestsNext: nothing for consumer, add them to _waitQcons
117
+
producer: started. _next = 0
118
+
fifo: requestToProduce(next=0) allows producer to produce id = 0 since _buf.size = 2 and _promised = 0 together are < _cap == 2
119
+
producer: has produced 0
120
+
fifo: dispatch() is taking consumer off _waitQcons to provide them next = 0
121
+
fifo: requestToProduce(next=1) allows producer to produce id = 1 since _buf.size = 2 and _promised = 0 together are < _cap == 2
122
+
consumer: has consumed 0
123
+
producer: has produced 1
124
+
consumer: about to ask for _next = 1
125
+
fifo: requestToProduce(next=2) allows producer to produce id = 2 since _buf.size = 2 and _promised = 0 together are < _cap == 2
126
+
fifo: consumerRequestsNext() has _buf.size = 2
127
+
fifo: consumerRequestsNext about to provide = 1 ; now _buf.size = 2
128
+
producer: has produced 2
129
+
consumer: has consumed 1
130
+
consumer: about to ask for _next = 2
131
+
fifo: consumerRequestsNext() has _buf.size = 2
132
+
fifo: consumerRequestsNext about to provide = 2 ; now _buf.size = 2
133
+
consumer: has consumed 2
134
+
elapsed nanosec = 186000
135
+
1 test started, 1 complete: fifo/basic complete
136
+
---- Passed: fifo/basic
137
+
----
138
+
---- 1 test ran.
139
+
---- Passed: 1
37
140
```
38
141
39
142
## Program Modifications
40
143
41
-
Rather than modifying this program, pay attention to how the use of behaviors means this program is non-blocking and does not use locks/semaphores.
144
+
# basic
145
+
146
+
1. Read the assertions. Do they assert that the
147
+
consumer never consumes the same product twice?
148
+
If not, add an assertion to this effect.
149
+
150
+
2. Verify that the ordering invariant is maintained
151
+
in this code. Can we assert this in other places?
152
+
153
+
In other words, assert that the reader consumes products
154
+
in the same sequential order that the producer produced them.
155
+
156
+
(Formally, the consumption and production sequences should map one-to-one
157
+
to the natural numbers.)
158
+
159
+
3. Try adding more than one consumer. How do the invariants change?
160
+
161
+
4. Try adding more than one producer. How do the invariants change?
162
+
163
+
# medium
164
+
165
+
5. Try sending and reading in batches, rather than one by one.
166
+
167
+
6. Try having an unbounded buffer rather than a fixed size one.
168
+
169
+
7. Cancellation
170
+
171
+
How do we avoid leaking memory or queue resources
172
+
if the producer or consumer wants to depart and
173
+
abandon its half-started consume or produce?
174
+
175
+
Implement a mechanism for clean departure, including
176
+
a means for both the producer and the consumer
177
+
to get acknowledgement that the buffer has
178
+
actually cancelled all outstanding requests.
179
+
180
+
What is the hazard in a real system if this
181
+
feature is missing? Hint: why does TCP
182
+
have the TIME_WAIT state?
183
+
184
+
# advanced
185
+
186
+
8. Optimistic batching
187
+
188
+
Rather than asking for permission, what if the
189
+
system was optimistic, and then asked for forgiveness?
190
+
191
+
That is, could the system be optimized by having the producer
192
+
send a batch of everything it has on hand and letting the buffer discard
193
+
what it cannot take, since its information about
194
+
how many slots are free might be stale by the time
195
+
the product batch arives?
196
+
197
+
This is based on the observation that there might be more
198
+
free slots now, since the consumer might done alot of
199
+
consuming since the original produce permission was granted.
200
+
201
+
This tends to happen especially in networks with large
202
+
bandwidth-delay products, like satellite links.
203
+
There, WAN network protocols like UDT[4], deploy this
204
+
optimization. But it can happen in any parallel setting.
205
+
206
+
How would the buffer communicate back how many it
207
+
could not store? This would require the producer
208
+
to have its own in-actor buffer. Would this extra memory
209
+
be worth it? What would you measure to tell?
210
+
Try it and find out.
211
+
212
+
9. Cutting down on communication
213
+
214
+
Pony's iso references means that the buffer might actually
215
+
be owned by the consumer or producer, rather than
216
+
in a third actor (the buffer).
217
+
218
+
Would there be benefit to trying to "cut out the middle man", and
219
+
directly communicate between only two actors instead of three?
220
+
221
+
Implement this, and measure if it yields higher throughtput.
222
+
223
+
224
+
## Questions to think about
225
+
226
+
What is the optimal buffer size?
227
+
228
+
Does it depend on which is faster, the consumer or the producer?
229
+
230
+
If the buffer size is unbounded, under what circumstances
231
+
should we expect the kernel to OOM kill our program for
0 commit comments