{"id":34813725,"url":"https://github.com/akaigoro/df4j","last_synced_at":"2026-01-11T17:35:17.918Z","repository":{"id":1186636,"uuid":"1089023","full_name":"akaigoro/df4j","owner":"akaigoro","description":"Lightweight dataflow Java library. Includes various asynchronous constructs, including actors and asynchronous I/O requests.","archived":false,"fork":false,"pushed_at":"2023-05-09T18:25:24.000Z","size":2776,"stargazers_count":100,"open_issues_count":1,"forks_count":19,"subscribers_count":7,"default_branch":"API-8","last_synced_at":"2026-01-03T07:42:50.445Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akaigoro.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-2.0.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2010-11-17T17:01:25.000Z","updated_at":"2025-12-23T12:20:06.000Z","dependencies_parsed_at":"2023-07-07T01:01:42.529Z","dependency_job_id":null,"html_url":"https://github.com/akaigoro/df4j","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/akaigoro/df4j","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akaigoro%2Fdf4j","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akaigoro%2Fdf4j/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akaigoro%2Fdf4j/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akaigoro%2Fdf4j/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akaigoro","download_url":"https://codeload.github.com/akaigoro/df4j/tar.gz/refs/heads/API-8","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akaigoro%2Fdf4j/sbom","scorecard":{"id":175166,"data":{"date":"2025-08-11","repo":{"name":"github.com/akaigoro/df4j","commit":"c9d37376d2e7eecc89d506270956f5ceb1ca7a28"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/30 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE-2.0.txt:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'API-8'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-16T17:32:32.560Z","repository_id":1186636,"created_at":"2025-08-16T17:32:32.560Z","updated_at":"2025-08-16T17:32:32.560Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28315879,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-11T14:58:17.114Z","status":"ssl_error","status_checked_at":"2026-01-11T14:55:53.580Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-12-25T13:00:26.962Z","updated_at":"2026-01-11T17:35:17.912Z","avatar_url":"https://github.com/akaigoro.png","language":"Java","funding_links":[],"categories":["并发编程"],"sub_categories":["Spring Cloud框架"],"readme":"# Data Flow For Java\n\nSimplicity is prerequisite for reliability. - Edsger W. Dijkstra\n------------------------------------------\n\ndf4j is an abbreviation of \"Data Flow for Java\".\nIt is a library to support asynchronous computations of all flavours: futures, promises, asynchronous procedure calls, actors, reactive streams.\n\nFor those interested in the history of actorGroup programming, I recommend to start with the [definition in Wikipedia](https://en.wikipedia.org/w/index.php?title=Dataflow_programming)\nand then short introductory article \"Dataflow Programming: Concept, Languages and Applications\" by Tiago Boldt Sousa.\n\nThe primary goal of this library is to investigate the anatomy of asynchronous programming.\nSo this project avoids highly optimized cryptic code usually found in such libraries. The main goal is to make readable code.\n\nThe asynchronous programming always attracted Java programmers,\nand the absence of a complete asynchronous support in language and runtime only stimulated programmers to find their own solutions.\nToday some asynchronous libraries for Java are very popular, e.g. RxJava, vert.x, Akka.\nHowever, all they imply steep learning curve and hides implementation details under the hood.\nDf4j ia an attempt to discover the basic building elements of asynchronous computations,\nand allow developer to freely combine those elements, and add new ones.\nIt resembles children's building kit: a set of small parts which can be connected together and be assembled in arbitrary complex constructs.\n\nThe design of Df4j is built on following foundation principles:\n\n1. Any asynchronous computation can be represented as a (actorGroup) graph, which consists of active nodes and nested actorGroup graphs.\nSuch a tree structure allows exceptions propagate from leafs to the root graph, and to watch exceptions only at the root node.\n\n2. Active node, in turn,  consists of:\n - ports: asynchronous input and output parameters. Each port is a (relatively complex) object.\n - user-defined computational procedure,\n - reference to an Executor, and\n - an object that glues all that components together, usually a descendant of class org.df4f.core.actorGroup.AsyncProc.  \n \n3. Each port has 2 states: ready and blocked. Input port is ready when it has received a token. \nOutput port is ready when it has room to store a new token.\nOutput ports for signals are always ready, as storing signals requires only a counter.\nSimilary, output ports for scalar messages are always ready. \nThe node is submitted to the attached executor when all its ports become ready.\nThen the user-defined computational procedure is executed.\n\n4. Nodes are interconnected so that output port of one node is connected to an input port of another node. \nConnected ports must support the same communication protocol.\nSome ports may support more than one protocol.\n\nCurrently Df4j has ports for following protocols:\n\n1. Signal flow. This is the asynchronous variant of the protocol used by java.util.concurrent.Semaphore. \n2. Scalar messages: this is the protocol similar to that used by java.util.concurrent.CompletableFuture. At most one message or an error is sent.\n3. Unbound message streams, without backpressure. Backpressure can be added later using permit stream and can connect far standing nodes.\n4. Reactive message flow with backpressure, identical to that defined in the package org.reactivestreams and/or class java.util.concurrent.Flow.\n   This allows to connect DF4J actors with RxJava and Reactor objects.\n4. Reversed reactive message flow with backpressure. It is similar to the reactive message stream described above, \nbut messages are sent not from Publisher to Subscribers, but from Subscribers to Publisher, which are named Producers and Consumers, respectively. \nThis protocol is an asynchronous analog to the input part of the interface of java.util.concurrent.BlockingQueue (method put(T)),\nwhile org.reactivestreams protocol is in fact asynchronous analogue of the output part of that interface. \n\nInput and output ports can be connected directly, or via connectors - special nodes which provide temporary memory for tokens.\nThe most significant connector is AsyncArrayBlockingQueue. It implements both asynchronous and synchronous access.\nSynchronous access is a subset of the interface java.util.concurrent.BlockingQueue.\nIt provide bufferization of messages and interoperability with threads. \n \n## The main results of this work\n\n1. Differentiation between nodes and ports. Nodes define behaviour, ports define communications.\nThis allows to develop ports independently of nodes and make use of new protocols with already developed node types.\nAs a result, this library is very compact. \nIt does not contain fluent API and does not try to implement [all combinations of all capabilities](https://www.google.ru/search?q=\"all+combinations+of+all+capabilities),\nbut allow developers to freely combine existing and newly developed capabilities.\n\n2. The type hierarchy of the active nodes is based on two fundamental classes: \n- AsyncProc for single-shot computations\n- (actorGroup) Actor for recurrent computations\n\n3. AsyncProc, being an asynchronous procedure, does not return value (or better say, returns void value).\nIts simple extension AsyncFunc\u003cT\u003e returns a value of arbitrary reference type T.\n\n4. Actor is provided with machinery to implement finite state machine which can be defined by a flow chart. \nThis allows to transform parallel algorithm into asynchronous mechanically, preserving the semantics.\nSee the test DiningPhilosophers as an example of such transformation.\n\n5. Hewitt's Actor (e.g. [Akka](https://akka.io/)) is no more than a actorGroup Actor with single input message flow parameter.\n\n6. Each communication protocol can be implemented in both synchronous and asynchronous forms. \nEspecially useful are nodes which support both synchronous and asynchronous versions.\nThus, the class org.df4j.core.communicator.AsyncSemaphore extends java.util.concurrent.Semaphore with implementation of SignalFlow.Publisher.\nClass AsyncArrayBlockingQueue partially implements java.util.concurrent.BlockingQueue, ReverseFlow.Publisher, and Flow.Publisher. \nSuch communicators can help when transforming multithreading program to asynchronous form.\n\n7. Reactive streams are just implementation of a specific protocol, and that protocol is no more but a combination of two more simple protocols. \nReactive streams in asynchronous programming plays the same role as blocking queues in multithreading programming: probably most useful,\nbut by far not the only way to connect independent parties. \n\nSee examples and test directories for various custom-made actorGroup objects and their usage.\n\nIf you find a bug or have a proposal, create an issue at \u003chttps://github.com/akaigoro/df4j/issues/new\u003e,\nor send email to alexei.kaigorodov(at)gmail.com.\n\n## Module structure:\n\n[df4j-protocols](/df4j-protocols/README.md) - Communication interfaces for df4j. All other modules depend on it. \nThis module can be used independently of others. To use it, add maven dependency\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.df4j\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003edf4j-protocols\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e8.3\u003c/version\u003e\n\t\t\u003c/dependency\u003e\n\t\t\n[df4j-core](/df4j-core/README.md) - The main module. Contains various predefined types of asynchronous nodes and ports.\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.df4j\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003edf4j-core\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e8.3\u003c/version\u003e\n\t\t\u003c/dependency\u003e\n\n[df4j-nio2](/df4j-nio2/README.md) - wrappers for NIO2 classes, compatible with df4j interfaces\n\t\t\u003cdependency\u003e\n\t\t\t\u003cgroupId\u003eorg.df4j\u003c/groupId\u003e\n\t\t\t\u003cartifactId\u003edf4j-nio2\u003c/artifactId\u003e\n\t\t\t\u003cversion\u003e8.3\u003c/version\u003e\n\t\t\u003c/dependency\u003e\n\n[df4j-reactivestreamsTCK](/df4j-reactivestreamsTCK) - runs df4j implementation against reactive streams tests (\u003chttps://github.com/reactive-streams/reactive-streams-jvm/tree/master/tck\u003e)\n\n[df4j-tutorial](/df4j-tutorial/README.md) - Simple and advanced usages of actorGroup and classic actors.\n \n Version history\n-----------------\n2020/10/31\nversion 8.4.\nuniversal method whenComplete(exception) introduced.\nclass PortGroup is a port with child ports, unblocks when any child is unblocks.\nPackage dataflow renaed to actor.\n\n2020/02/18\nversion 8.3.\nSynchronization with ReentrantLocks of different levels replaced with plain synchronized(parentActor).\nMethod InpMessagePort.current renamed to InpMessagePort.peek().\n\n2020/02/05\nversion 8.2.\nBasicBlock eliminated. AsyncProc became the root async node. \nMethods awake() and awake(long delay) eliminated. \nFunctionality of BasicBlock is modelled with Actor and new stop() method.\nOld stop methods renamed to onComplete and onError.\nActor has new methods nextAction(ThrowingRunnable), suspend(), and delay(millis), to model a control flow chart.\n\n2019/12/30\nversion 8.0.\nAll the tests passed, including those from reactive TCK. \nThe branch API-8 becomes the default branch of the https://github.com/akaigoro/df4j project.\n\n2019/08/26 \nBranch API-8 started: protocols refactored; total simplification. \nReverseFlow and AsyncBlockingQueue introduced.\n\n2019/06/16\ntag 7.2 protocol interfaces are grouped in a separate module df4j-protocols.\n\n2019/05/04\nBranch API-7 and tag ver7.0 created.\ntag ver7.1: scalars made compatible with RxJava2\n\n2018/07/15\nBranch API-5 and tag ver5.0.1 created.\n\n2018/07/10\nTag ver4.2 in branch API-4 created.\n\n2018/05/16\nTag ver4.1 in branch API-4 created.\n\n2018/05/06\nBranch API-4 and tag ver4.0 created.\n\n2017/10/20\npom.xml files corrected. Branch API-3 and tag ver3.1 created.\n\n2015/06/21\nConverted to multimodule maven project. Previuos df4j project is now module df4j-core.\n\n2015/06/20\nFurther codebase and interface minimization, version number 3.0\n\n20/06/15\nv1 branch development freesed, tagged as  df4j-core-v1.0\nv2 branch development freesed, tagged as  df4j-core-v2.0\n\n2014/04/06\nRefactored for more clean design and structure. Interface cahnged, version number 2.0  \n\n2013/09/01\ndf4j-core proved to be stable, so version number 1.0 is assigned.  \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakaigoro%2Fdf4j","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakaigoro%2Fdf4j","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakaigoro%2Fdf4j/lists"}