
groovyx.gpars.dataflow.KanbanFlow.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gpars Show documentation
Show all versions of gpars Show documentation
The Groovy and Java high-level concurrency library offering actors, dataflow, CSP, agents, parallel collections, fork/join and more
// GPars - Groovy Parallel Systems
//
// Copyright © 2008-11 The original author or authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package groovyx.gpars.dataflow
import groovyx.gpars.GParsConfig
import groovyx.gpars.group.DefaultPGroup
import groovyx.gpars.group.PGroup
/**
* A KanbanFlow is a network of dataflow connections made up from {@link KanbanLink}s.
* Links can be arranged as to form a chain (1:1), a fork (1:n), a funnel (n:1),
* a diamond (1:n:1) and any other acyclic directed graph by composition.
* Cycles are disallowed by
* default but can be made possible by setting the cycleAllowed property to true.
* All {@link KanbanLink}s in a KanbanFlow share the same PGroup. Per default this group uses a
* resizeable pool of daemon threads, starting with the GPars default pool size. This can be overridden
* by setting the pooledGroup property to a custom PGroup.
* @see KanbanLink
* @author Dierk Koenig
*/
class KanbanFlow {
protected List links = []
/** If adapted, this must be set before calling link() */
boolean cycleAllowed = false
/** If adapted, this must be set before calling start() */
PGroup pooledGroup = new DefaultPGroup(GParsConfig.retrieveDefaultPool()) // default pool size
/**
* First part of the sequence link producer to consumer
.
*/
KanbanLink link(ProcessingNode producer) {
assert producer != null
new KanbanLink(producerSpec: producer, flow: this)
}
/** Start all {@link KanbanLink}s of this flow without any trays. **/
void startEmpty() {
assert links, "There is not much point in starting a flow that has no links."
links*.start()
}
/** Start all {@link KanbanLink}s of this flow with so many trays. **/
void start(int numberOfTrays) {
startEmpty()
numberOfTrays.times { links*.addTray() }
}
/** Start all {@link KanbanLink}s of this flow with as many trays per link as what is considered optimal. **/
void start() {
startEmpty()
links*.addOptimalNumberOfTrays()
}
/** Stop all {@link KanbanLink}s of this flow. **/
void stop() { links*.stop() } // note dk: needs investigation, maybe do it in reverse
/** Helper method that inverses the sequence of Closure parameters. **/
static Closure inverse(Closure body) {
{ a, b -> body b, a }
}
/** Composes two flows by adding a trailing one to the current one, returning a new one.
* {@link KanbanLink}s maintain their state beside that the last link of the current flow
* is linked to the first link of the trailing flow.
* */
KanbanFlow plus(KanbanFlow trailingFlow) {
def flow = new KanbanFlow()
flow.links.addAll links
def spec = trailingFlow.links.first().producerSpec
spec.body = inverse(spec.body) // since trailingFlow has been wired already, sequence would be switched
flow.link(links.last().consumerSpec).to(spec)
flow.links.addAll trailingFlow.links
return flow
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy