structurizr / dsl

Structurizr DSL
https://docs.structurizr.com/dsl
Apache License 2.0
1.41k stars 265 forks source link

Parallel sequence behavior in dynamic views #114

Closed juanrferia closed 1 year ago

juanrferia commented 2 years ago

Given the following example of dynamic view including parallel sequence:

workspace {

    model {
        a = softwareSystem "A"
        b = softwareSystem "B"
        c = softwareSystem "C"
        d = softwareSystem "D"
        e = softwareSystem "E"

    }

    views {

        dynamic * {
            a -> b "Get data (id)"
            {
                b -> c "Get some subset 1 of data (id)"
                c -> b "Subset 1 of data" 
            }
            {
                b -> d "Get some subset 2 of data (id)"
                d -> b "Subset 2 of data"
            }
            {
                b -> e "Get some subset 3 of data (id)"
                e -> b "Subset 3 of data"
            }

            b -> a "Data"

            autoLayout
        }
    }

}

I was expecting after those three parallel activites are finished then b -> a message would be activated. However, I see that message is actually activated in parallel with b -> c , b -> d and b -> e. I would expect that behaviour if I defined it in that way:

...
            {
                b -> c "Get some subset 1 of data (id)"
                c -> b "Subset 1 of data" 
            }
            {
                b -> d "Get some subset 2 of data (id)"
                d -> b "Subset 2 of data"
            }
            {
                b -> e "Get some subset 3 of data (id)"
                e -> b "Subset 3 of data"
            }
            {
                b -> a "Data"
            }
...

Can you clarify if that is an issue or maybe expected behaviour?

Thanks

simonbrowndotje commented 2 years ago

There's a feature on the underlying Java library that isn't exposed via the DSL, so there are two workarounds until I figure out how best to add it.

Option 1

The first is to include your final step(s) inside one of the parallel blocks:

workspace {

    model {
        a = softwareSystem "A"
        b = softwareSystem "B"
        c = softwareSystem "C"
        d = softwareSystem "D"
        e = softwareSystem "E"
    }

    views {

        dynamic * {
            a -> b "Get data (id)"
            {
                b -> c "Get some subset 1 of data (id)"
                c -> b "Subset 1 of data" 
            }
            {
                b -> d "Get some subset 2 of data (id)"
                d -> b "Subset 2 of data"
            }
            {
                b -> e "Get some subset 3 of data (id)"
                e -> b "Subset 3 of data"
                b -> a "Data"
            }

            autoLayout
        }
    }

}

Option 2

The second is to use inline scripts to call the feature that isn't exposed via the DSL:

workspace {

    model {
        a = softwareSystem "A"
        b = softwareSystem "B"
        c = softwareSystem "C"
        d = softwareSystem "D"
        e = softwareSystem "E"
    }

    views {

        dynamic * "key" {
            autoLayout
            a -> b "Get data (id)"

            {   
                b -> c "Get some subset 1 of data (id)"
                c -> b "Subset 1 of data" 
            }

            {   
                b -> d "Get some subset 2 of data (id)"
                d -> b "Subset 2 of data"
            }

            !script groovy {
                workspace.views.getViewWithKey("key").startParallelSequence()
            }
                b -> e "Get some subset 3 of data (id)"
                e -> b "Subset 3 of data"
            !script groovy {
                workspace.views.getViewWithKey("key").endParallelSequence(true)
            }

            b -> a "Data"
        }
    }

}
juanrferia commented 2 years ago

Thanks Simon. I'll add a workaround until it is fixed in DSL.

simonbrowndotje commented 1 year ago

You'll be able to do the following once a new version of the DSL library is released:

dynamic * {
    a -> b "Get data (id)"

    {
        {
            b -> c "Get some subset 1 of data (id)"
            c -> b "Subset 1 of data" 
        }
        {
            b -> d "Get some subset 2 of data (id)"
            d -> b "Subset 2 of data"
        }
        {
            b -> e "Get some subset 3 of data (id)"
            e -> b "Subset 3 of data"
        }
    }

    b -> a "Data"

    autoLayout
}
dgutson commented 1 year ago

if you could allow just an additional keyword to that block, "alt", "for", ... :)