{"id":37026133,"url":"https://github.com/m3dev/multilane","last_synced_at":"2026-01-14T03:02:00.166Z","repository":{"id":3425605,"uuid":"4477156","full_name":"m3dev/multilane","owner":"m3dev","description":"Multi-lane Expressway to Aggregate Values in Parallel","archived":true,"fork":false,"pushed_at":"2013-06-09T15:22:20.000Z","size":321,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":68,"default_branch":"master","last_synced_at":"2025-12-16T13:30:30.496Z","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":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m3dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-05-29T03:26:48.000Z","updated_at":"2023-01-28T16:49:43.000Z","dependencies_parsed_at":"2022-09-26T21:50:46.409Z","dependency_job_id":null,"html_url":"https://github.com/m3dev/multilane","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/m3dev/multilane","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m3dev%2Fmultilane","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m3dev%2Fmultilane/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m3dev%2Fmultilane/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m3dev%2Fmultilane/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m3dev","download_url":"https://codeload.github.com/m3dev/multilane/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m3dev%2Fmultilane/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408800,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":"2026-01-14T03:01:59.385Z","updated_at":"2026-01-14T03:02:00.139Z","avatar_url":"https://github.com/m3dev.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# multilane\n\n'multilane' is a multi-lane expressway to aggregate values in parallel.\n\n# Setup\n\n## Maven\n\nAvailable on the maven central repository. Add the following dependency:\n\n```xml\n\u003cdependencies\u003e\n  \u003cdependency\u003e\n    \u003cgroupId\u003ecom.m3\u003c/groupId\u003e\n    \u003cartifactId\u003emultilane\u003c/artifactId\u003e\n    \u003cversion\u003e[1.0,)\u003c/version\u003e\n  \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\nCAUTION: Don't use older version than 1.0.5. The previous versions have [a critical bug](https://github.com/m3dev/multilane/issues/1).\n\n## Example\n\n### Basic MultiLane Usage\n\nSimply aggregate same type values.\n\n```java\nMultiLane\u003cString, Result\u003e multiLane = new MultiLaneTemplate\u003cString, Result\u003e {};\n\nint timeoutMillis = 1000;\nmultiLane.start(\"part1\", new InputAction\u003cString, Result\u003e(\"A\", timeoutMillis) {\n  protected Result process(String input) throws Exception {\n    return doSomething(input);\n  }\n});\nmultiLane.start(\"part2\", new InputAction\u003cString, Result\u003e(\"B\", timeoutMillis) {\n  protected Result process(String input) throws Exception {\n    return doSomething(input);\n  }\n}, Result.Failed); // with default value\n\n// Use #collect() if you want to handle each action's failure\nMap\u003cString, Either\u003cThrowable, Result\u003e\u003e result = multiLane.collect();\n\n// Use #collectValues() if you just want to aggregate values\n// It'll use null or default value if action failed or timed out)\nMap\u003cString, Result\u003e resultMap = multiLane.collectValues();\n```\n\nOr use built-in if possible.\n\n```java\nHttpGetToStringMultiLane multiLane = new HttpGetToStringMultiLane();\n\nlong timeoutMillis = 2500L;\nHttpGetToStringAction action1 = new HttpGetToStringAction(\"http://localhost:8080/api/1s\", timeoutMillis);\nHttpGetToStringAction action2 = new HttpGetToStringAction(\"http://localhost:8080/api/2s\", timeoutMillis);\nHttpGetToStringAction action3 = new HttpGetToStringAction(\"http://localhost:8080/api/3s\", timeoutMillis);\n\nString unavailable = \"\u003cli\u003eUnavailable\u003c/li\u003e\";\n\nmultiLane.start(\"p1\", action1, unavailable);\nmultiLane.start(\"p2\", action1, unavailable);\nmultiLane.start(\"p3\", action1, unavailable);\nmultiLane.start(\"p4\", action2, unavailable);\nmultiLane.start(\"p5\", action2, unavailable);\nmultiLane.start(\"p6\", action3, unavailable);\n\n// Blocking here!\nMap\u003cString, String\u003e parts = multiLane.collectValues();\n/*\n Map(\n   \"p1\" -\u003e \"\u003cli\u003eResponse in 1s\u003c/li\u003e\",\n   \"p2\" -\u003e \"\u003cli\u003eResponse in 1s\u003c/li\u003e\",\n   \"p3\" -\u003e \"\u003cli\u003eResponse in 1s\u003c/li\u003e\",\n   \"p4\" -\u003e \"\u003cli\u003eResponse in 2s\u003c/li\u003e\",\n   \"p5\" -\u003e \"\u003cli\u003eResponse in 2s\u003c/li\u003e\",\n   \"p6\" -\u003e \"\u003cli\u003eUnavailable\u003c/li\u003e\"\n )\n */\n\n// or handle Either values if you need to check the errors\nMap\u003cString, Either\u003cThrowable, String\u003e\u003e results = multiLane.collect();\n```\n\n### ActionToBeanMultiLane Usage\n\nAggregate result values as Java bean fields.\n\n```java\npublic static class Profile {\n\n  private Name name;\n  private Integer age;\n\n  public Name getName() { return name; }\n  public void setName(Name name) { this.name = name; }\n  public Intger getAge() { return age; }\n  public void setAge(Integer age) { this.age = age; }\n}\n\nActionToBeanMultiLane multiLane = new ActionToBeanMultiLane();\n\nint timeoutMillis = 1000;\nmultiLane.start(\"name\", new InputAction\u003cString, Name\u003e(\"alice\", timeoutMillis) {\n  public Name process(String input) throws Exception {\n    return new Name(input.toUpperCase());\n  }\n});\nmultiLane.start(\"age\", new NoInputAction\u003cInteger\u003e(timeoutMillis) {\n  public Integer process() throws Exception {\n    return 20;\n  }\n});\n\nProfile profile = multiLane.collectValuesAsBean(Profile.class);\nprofile.getName(); // \"ALICE\"\nprofile.getAge(); // 20\n```\n\n\n## License\n\nCopyright 2012 M3, Inc.\n\nApache License, Version 2.0\n\nhttp://www.apache.org/licenses/LICENSE-2.0.html\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm3dev%2Fmultilane","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm3dev%2Fmultilane","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm3dev%2Fmultilane/lists"}