I need to do this kind of work:
- Get Page object from database
- For each page get all images and process them (IO bound, for example, upload to CDN)
- If all images proceeded successfully then mark Page as processed in database
Since I need to control how much Pages I process in parallel I've decided to go with TPL Dataflows:
____________________________
| Data pipe |
| BufferBlock<Page> |
| BoundedCapacity = 1 |
|____________________________|
|
____________________________
| Process images |
| TransformBlock<Page, Page> |
| BoundedCapacity = 1 |
| MaxDegreeOfParallelism = 8 |
|____________________________|
|
____________________________
| Save page |
| ActionBlock<Page> |
| BoundedCapacity = 1 |
| MaxDegreeOfParallelism = 5 |
|____________________________|
Now I need the "Process images" to process images in parallel but I want to limit how much images I've processing across all parallel pages in work currently.
I can use TrasnformManyBlock for "Process images" but how do I gather them back in "Save page" block?
____________________________
| Data pipe |
| BufferBlock<Page> |
| BoundedCapacity = 1 |
|____________________________|
|
___________________________________
| Load images |
| TransformManyBlock<Page, Image[]> |
| BoundedCapacity = 1 |
| MaxDegreeOfParallelism = 8 |
|___________________________________|
/ | \
______________________________________________
_|____________________________________________ |
| Process image | |
| TransformBlock<ImageWithPage, ImageWithPage> | |
| BoundedCapacity = 1 | |
| MaxDegreeOfParallelism = 8 |_|
|______________________________________________|
\ | /
How to group images by page ?
|
____________________________
| Save page |
| ActionBlock<Page> |
| BoundedCapacity = 1 |
| MaxDegreeOfParallelism = 5 |
|____________________________|
On top of that potentially one of the images could fail to be proceed and I don't want to save page with failed images.