Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
bf1de4f
remove current implementation
Baptouuuu Mar 7, 2026
64b8682
setup project
Baptouuuu Mar 7, 2026
06b21d8
lay out the new api
Baptouuuu Mar 7, 2026
55428ad
add dummy test
Baptouuuu Mar 7, 2026
fa819e4
implement protocol messages
Baptouuuu Mar 8, 2026
d42a257
add protocol
Baptouuuu Mar 8, 2026
5d3b02d
implement process logic to send/receive messages
Baptouuuu Mar 8, 2026
1f4cc11
implement logic to connect to a process
Baptouuuu Mar 8, 2026
9d2c7d5
CS
Baptouuuu Mar 8, 2026
6a871ce
require the whole OS to be injected in the IPC
Baptouuuu Mar 8, 2026
b611e48
implement server accepting connections and waiting for messages
Baptouuuu Mar 8, 2026
fb95116
lay out the system to combine clients results
Baptouuuu Mar 8, 2026
1d58b09
allow to stop the server
Baptouuuu Mar 8, 2026
e938dad
allow for a client to respond to received messages
Baptouuuu Mar 8, 2026
6577a67
use a property to keep track if a client must be aborted
Baptouuuu Mar 8, 2026
1b17d04
wait for acknowledgements of sent messages
Baptouuuu Mar 8, 2026
be58bf9
centralize the way to wait for messages
Baptouuuu Mar 8, 2026
f679cff
extract logic to wait/send messages
Baptouuuu Mar 8, 2026
7d90f67
reuse the pipe for waiting/sending messages from the server side
Baptouuuu Mar 8, 2026
dd4e56b
implement connection handshake on server side
Baptouuuu Mar 8, 2026
5ec7ca5
fix docblock
Baptouuuu Mar 8, 2026
b5ec4f3
CS
Baptouuuu Mar 8, 2026
ffa4a6c
use a dedicated object to know if the stream must be aborted due to s…
Baptouuuu Mar 14, 2026
212e946
avoid capturing $this
Baptouuuu Mar 14, 2026
4111a1d
avoid capturing $this
Baptouuuu Mar 14, 2026
b8d785c
rename Abort::new() to ::disabled()
Baptouuuu Mar 14, 2026
fc535b2
force the use of Abort in the Pipe
Baptouuuu Mar 14, 2026
42009d6
allow to listen for signals on the client side
Baptouuuu Mar 14, 2026
1cdde0e
switch the methods on Abort to simplify removing the object as a list…
Baptouuuu Mar 14, 2026
7b1c090
remove the abort listener when the process is closed
Baptouuuu Mar 14, 2026
d12d567
check for aborts when sending messages
Baptouuuu Mar 14, 2026
9458e4d
move the abort logic inside the Pipe
Baptouuuu Mar 14, 2026
c864190
stop the server when it is signaled to terminate
Baptouuuu Mar 14, 2026
d34fa79
flag internals
Baptouuuu Mar 14, 2026
3f11b52
CS
Baptouuuu Mar 14, 2026
06c2020
flag pure methods/classes
Baptouuuu Mar 14, 2026
cc524a6
add NoDiscard on methods returning monads
Baptouuuu Mar 14, 2026
768f169
make sure to read socket as ascii strings
Baptouuuu Mar 14, 2026
59f2d64
use tmp as default folder
Baptouuuu Mar 14, 2026
3b29646
automatically create the folder used to store sockets
Baptouuuu Mar 14, 2026
68ba287
fix watching for server sockets files
Baptouuuu Mar 14, 2026
9e10ca3
fix waiting for an ack that will never arrive
Baptouuuu Mar 14, 2026
e568ca7
fix waiting for an ack message after a connection start ok
Baptouuuu Mar 14, 2026
963e810
fix waiting to connect to the server process
Baptouuuu Mar 14, 2026
8a4cf93
add server fixture
Baptouuuu Mar 14, 2026
c923c93
add test to check for wait timeout
Baptouuuu Mar 14, 2026
a15292b
expect closure handshake when closing the process
Baptouuuu Mar 14, 2026
dbc8647
correctly handle when the client ask to close the connection
Baptouuuu Mar 14, 2026
0c7531a
test wait for message
Baptouuuu Mar 14, 2026
7f04b34
always take over the server socket
Baptouuuu Mar 14, 2026
1312f09
call the monitor only when the carried value changed based on clients…
Baptouuuu Mar 14, 2026
ac9b9e7
test the server can accept connections
Baptouuuu Mar 14, 2026
53533ef
fix losing the carried value when the client properly closes the conn…
Baptouuuu Mar 14, 2026
245d0ae
generate messages to prove it is not hardcoded behaviour
Baptouuuu Mar 14, 2026
b482299
test for processes
Baptouuuu Mar 14, 2026
e86a434
test defautl folding
Baptouuuu Mar 14, 2026
dd5ea41
test connection timeout
Baptouuuu Mar 14, 2026
e046f40
test listening for signals
Baptouuuu Mar 14, 2026
9bffabe
test message equality
Baptouuuu Mar 14, 2026
8e740d2
test client quick connection close
Baptouuuu Mar 14, 2026
b39cc53
remove the abort listener when the scope exits
Baptouuuu Mar 15, 2026
b40923f
update readme
Baptouuuu Mar 15, 2026
d7a7d00
update changelog
Baptouuuu Mar 15, 2026
27c05b9
remove implemented comment
Baptouuuu Mar 15, 2026
3ef6588
better prove message equality depending on the media type
Baptouuuu Mar 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
/.gitattributes export-ignore
/.gitignore export-ignore
/phpunit.xml.dist export-ignore
/fixtures export-ignore
/tests export-ignore
/proofs/ export-ignore
74 changes: 8 additions & 66 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,72 +1,14 @@
name: CI

on: [push]
on: [push, pull_request]

jobs:
phpunit:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest]
php-version: ['8.2', '8.3']
dependencies: ['lowest', 'highest']
name: 'PHPUnit'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
coverage: xdebug
- name: Composer
uses: "ramsey/composer-install@v2"
with:
dependency-versions: ${{ matrix.dependencies }}
- name: PHPUnit
run: vendor/bin/phpunit --coverage-clover=coverage.clover --stop-on-error
env:
CI: 'github'
- uses: codecov/codecov-action@v1
with:
token: ${{ secrets.CODECOV_TOKEN }}
blackbox:
uses: innmind/github-workflows/.github/workflows/black-box-matrix.yml@main
coverage:
uses: innmind/github-workflows/.github/workflows/coverage-matrix.yml@main
secrets: inherit
psalm:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.2', '8.3']
dependencies: ['lowest', 'highest']
name: 'Psalm'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
- name: Composer
uses: "ramsey/composer-install@v2"
with:
dependency-versions: ${{ matrix.dependencies }}
- name: Psalm
run: vendor/bin/psalm --shepherd
uses: innmind/github-workflows/.github/workflows/psalm-matrix.yml@main
cs:
runs-on: ubuntu-latest
strategy:
matrix:
php-version: ['8.2']
name: 'CS'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring, intl
- name: Composer
uses: "ramsey/composer-install@v2"
- name: CS
run: vendor/bin/php-cs-fixer fix --diff --dry-run
uses: innmind/github-workflows/.github/workflows/cs.yml@main
12 changes: 12 additions & 0 deletions .github/workflows/extensive.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
name: Extensive CI

on:
push:
tags:
- '*'
paths:
- '.github/workflows/extensive.yml'

jobs:
blackbox:
uses: innmind/github-workflows/.github/workflows/extensive.yml@main
11 changes: 11 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: Create release

on:
push:
tags:
- '*'

jobs:
release:
uses: innmind/github-workflows/.github/workflows/release.yml@main
secrets: inherit
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
/composer.lock
/vendor
.phpunit.result.cache
.phpunit.cache
3 changes: 2 additions & 1 deletion .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

return Innmind\CodingStandard\CodingStandard::config([
'tests',
'fixtures',
'proofs',
'src',
]);
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,25 @@

## [Unreleased]

### Changed

- Requires PHP `8.4`
- Requires `innmind/foundation:~2.1`
- `Innmind\IPC\IPC` is a final class now
- `Innmind\IPC\Message` is a final class now
- `Innmind\IPC\Process\Name::maybe()` has been replace by `::attempt()`
- `Innmind\IPC\Process` is a final class now
- `Innmind\IPC\Protocol` is an internal final class now
- `Innmind\IPC\Server::__invoke()` has been replaced by `::with()`

### Removed

- `Innmind\IPC\Client\Unix`
- `Innmind\IPC\Exception\*`
- `Innmind\IPC\IPC\Unix`, use `Innmind\IPC\IPC` instead
- `Innmind\IPC\Message\*`, use `Innmind\IPC\Message` instead
- `Innmind\IPC\Factory`, use `Innmind\IPC\IPC::of()` instead

### Fixed

- PHP `8.4` deprecations
Expand Down
84 changes: 62 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Inter-Process Communication (IPC)

[![Build Status](https://github.com/Innmind/IPC/workflows/CI/badge.svg?branch=master)](https://github.com/Innmind/IPC/actions?query=workflow%3ACI)
[![CI](https://github.com/Innmind/IPC/actions/workflows/ci.yml/badge.svg?branch=master)](https://github.com/Innmind/IPC/actions/workflows/ci.yml)
[![codecov](https://codecov.io/gh/Innmind/IPC/branch/develop/graph/badge.svg)](https://codecov.io/gh/Innmind/IPC)
[![Type Coverage](https://shepherd.dev/github/Innmind/IPC/coverage.svg)](https://shepherd.dev/github/Innmind/IPC)

Expand All @@ -17,47 +17,87 @@ composer require innmind/ipc
```php
# Process A
use Innmind\IPC\{
Factory as IPC,
IPC,
Process\Name,
Continuation,
Server,
Message,
};
use Innmind\OperatingSystem\Factory;
use Innmind\Immutable\Monoid;

$ipc = IPC::build(Factory::build());
$counter = $ipc->listen(Name::of('a'))(0, static function($message, $continuation, $counter): void {
if ($counter === 42) {
return $continuation->stop($counter);
/**
* @psalm-immutable
* @implements Monoid<int>
*/
final class Addition implements Monoid
{
public function identity(): int
{
return 0;
}

public function combine(mixed $a, mixed $b): int
{
return $a + $b;
}
}

return $continuation->respond($counter + 1, $message);
})->match(
static fn($counter) => $counter,
static fn() => throw new \RuntimeException('Unable to start the server'),
);
$ipc = IPC::build(Factory::build());
$counter = $ipc
->serve(Name::of('a'))
->sink(new Addition)
->monitor(static fn(int $counter, Server\Continuation $continuation) => match ($counter) {
42 => $continuation->finish(),
default => $continuation,
})
->with(
static fn(Message $message, Continuation $continuation, int $counter) => $continuation
->respond($message)
->carryWith($counter + 1),
)
->unwrap();
// $counter will always be 42 in this case
```

```php
# Process B
use Innmind\IPC\{
Factory as IPC,
IPC,
Process,
Process\Name,
Message\Generic as Message,
Message,
};
use Innmind\OperatingSystem\Factory;
use Innmind\Immutable\Sequence;
use Innmind\MediaType\{
MediaType,
TopLevel,
};
use Innmind\Immutable\{
Str,
Sequence,
};

$ipc = IPC::build(Factory::build());
$server = Name::of('a');
$ipc
->wait(Name::of('a'))
->flatMap(fn($process) => $process->send(Sequence::of(
Message::of('text/plain', 'hello world'),
)))
->flatMap(fn($process) => $process->wait())
$response = $ipc
->connectTo($server)
->flatMap(
static fn(Process $process) => $process
->send(Sequence::of(
Message::of(
MediaType::from(TopLevel::text, 'plain'),
Str::of('hello world'),
),
))
->map(static fn() => $process),
)
->flatMap(fn(Process $process) => $process->wait())
->match(
static fn($message) => print('server responded '.$message->content()->toString()),
static fn() => print('no response from the server'),
static fn(Message $message) => 'server responded '.$message->content()->toString(),
static fn() => 'no response from the server',
);
print($message);
```

The above example will result in the output `server responded hello world` in the process `B`.
Expand Down
28 changes: 28 additions & 0 deletions blackbox.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
declare(strict_types = 1);

require 'vendor/autoload.php';

use Innmind\BlackBox\{
Application,
Runner\Load,
Runner\CodeCoverage,
};

Application::new($argv)
->map(static fn($app) => match (\getenv('BLACKBOX_ENV')) {
'coverage' => $app
->codeCoverage(
CodeCoverage::of(
__DIR__.'/src/',
__DIR__.'/proofs/',
)
->dumpTo('coverage.clover')
->enableWhen(true),
)
->scenariiPerProof(1),
'extensive' => $app->scenariiPerProof(1_000),
default => $app,
})
->tryToProve(Load::everythingIn(__DIR__.'/proofs/'))
->exit();
19 changes: 4 additions & 15 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,17 @@
"issues": "http://github.com/Innmind/IPC/issues"
},
"require": {
"php": "~8.2",
"innmind/immutable": "~4.15|~5.0",
"innmind/operating-system": "~5.0",
"innmind/url": "~4.0",
"innmind/media-type": "~2.0",
"innmind/socket": "~6.0",
"innmind/server-control": "~5.0"
"php": "~8.4",
"innmind/foundation": "~2.1"
},
"autoload": {
"psr-4": {
"Innmind\\IPC\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Tests\\Innmind\\IPC\\": "tests/"
}
},
"require-dev": {
"phpunit/phpunit": "~10.2",
"innmind/static-analysis": "^1.2.1",
"innmind/black-box": "~5.5",
"innmind/static-analysis": "~1.3",
"innmind/black-box": "~6.5",
"innmind/coding-standard": "~2.0"
}
}
Loading
Loading