Skip to content

Commit

Permalink
Merge pull request #3 from Innmind/reduce-circular-references
Browse files Browse the repository at this point in the history
Reduce circular references
  • Loading branch information
Baptouuuu authored Oct 26, 2024
2 parents e723eb4 + b354b59 commit e8311ae
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 33 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## [Unreleased]

### Changed

- Use `static` closures as much as possible to reduce the probability of creating circular references by capturing `$this` as it can lead to memory root buffer exhaustion.

## 2.3.0 - 2024-08-01

### Added
Expand Down
46 changes: 33 additions & 13 deletions src/Application/Async/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,10 +100,12 @@ public static function of(OperatingSystem $os): self
*/
public function mapEnvironment(callable $map): self
{
$previous = $this->map;

return new self(
$this->os,
function(OperatingSystem $os, Environment $env) use ($map): array {
[$os, $env] = ($this->map)($os, $env);
static function(OperatingSystem $os, Environment $env) use ($previous, $map): array {
[$os, $env] = $previous($os, $env);
$env = $map($env, $os);

return [$os, $env];
Expand All @@ -120,10 +122,12 @@ function(OperatingSystem $os, Environment $env) use ($map): array {
*/
public function mapOperatingSystem(callable $map): self
{
$previous = $this->map;

return new self(
$this->os,
function(OperatingSystem $os, Environment $env) use ($map): array {
[$os, $env] = ($this->map)($os, $env);
static function(OperatingSystem $os, Environment $env) use ($previous, $map): array {
[$os, $env] = $previous($os, $env);
$os = $map($os, $env);

return [$os, $env];
Expand All @@ -140,10 +144,12 @@ function(OperatingSystem $os, Environment $env) use ($map): array {
*/
public function service(string|Service $name, callable $definition): self
{
$container = $this->container;

return new self(
$this->os,
$this->map,
fn(OperatingSystem $os, Environment $env) => ($this->container)($os, $env)->add(
static fn(OperatingSystem $os, Environment $env) => $container($os, $env)->add(
$name,
static fn($service) => $definition($service, $os, $env),
),
Expand Down Expand Up @@ -207,18 +213,20 @@ public function appendRoutes(callable $append): self
*/
public function mapRequestHandler(callable $map): self
{
$previous = $this->mapRequestHandler;

return new self(
$this->os,
$this->map,
$this->container,
$this->routes,
fn(
static fn(
RequestHandler $handler,
Container $container,
OperatingSystem $os,
Environment $env,
) => $map(
($this->mapRequestHandler)($handler, $container, $os, $env),
$previous($handler, $container, $os, $env),
$container,
$os,
$env,
Expand All @@ -244,13 +252,25 @@ public function notFoundRequestHandler(callable $handle): self

public function run($input)
{
$map = $this->map;
$container = $this->container;
$routes = $this->routes;
$notFound = $this->notFound;
$mapRequestHandler = $this->mapRequestHandler;

$run = Commands::of(Serve::of(
$this->os,
function(ServerRequest $request, OperatingSystem $os): Response {
static function(ServerRequest $request, OperatingSystem $os) use (
$map,
$container,
$routes,
$notFound,
$mapRequestHandler,
): Response {
$env = Environment::http($request->environment());
[$os, $env] = ($this->map)($os, $env);
$container = ($this->container)($os, $env)->build();
$routes = Sequence::lazyStartingWith($this->routes)
[$os, $env] = $map($os, $env);
$container = $container($os, $env)->build();
$routes = Sequence::lazyStartingWith($routes)
->flatMap(static fn($routes) => $routes)
->map(static fn($provide) => $provide(
Routes::lazy(),
Expand All @@ -261,7 +281,7 @@ function(ServerRequest $request, OperatingSystem $os): Response {
->flatMap(static fn($routes) => $routes->toSequence());
$router = new Router(
$routes,
$this->notFound->map(
$notFound->map(
static fn($handle) => static fn(ServerRequest $request) => $handle(
$request,
$container,
Expand All @@ -270,7 +290,7 @@ function(ServerRequest $request, OperatingSystem $os): Response {
),
),
);
$handle = ($this->mapRequestHandler)($router, $container, $os, $env);
$handle = $mapRequestHandler($router, $container, $os, $env);

return $handle($request);
},
Expand Down
19 changes: 13 additions & 6 deletions src/Application/Cli.php
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,12 @@ public function mapOperatingSystem(callable $map): self
*/
public function service(string|Service $name, callable $definition): self
{
$container = $this->container;

return new self(
$this->os,
$this->env,
fn(OperatingSystem $os, Environment $env) => ($this->container)($os, $env)->add(
static fn(OperatingSystem $os, Environment $env) => $container($os, $env)->add(
$name,
static fn($service) => $definition($service, $os, $env),
),
Expand Down Expand Up @@ -144,18 +146,20 @@ public function command(callable $command): self
*/
public function mapCommand(callable $map): self
{
$previous = $this->mapCommand;

return new self(
$this->os,
$this->env,
$this->container,
$this->commands,
fn(
static fn(
Command $command,
Container $service,
OperatingSystem $os,
Environment $env,
) => $map(
($this->mapCommand)($command, $service, $os, $env),
$previous($command, $service, $os, $env),
$service,
$os,
$env,
Expand Down Expand Up @@ -198,11 +202,14 @@ public function notFoundRequestHandler(callable $handle): self
public function run($input)
{
$container = ($this->container)($this->os, $this->env)->build();
$mapCommand = fn(Command $command): Command => ($this->mapCommand)(
$mapCommand = $this->mapCommand;
$os = $this->os;
$env = $this->env;
$mapCommand = static fn(Command $command): Command => $mapCommand(
$command,
$container,
$this->os,
$this->env,
$os,
$env,
);
$commands = $this->commands->map(static fn($service) => new Defer(
$service,
Expand Down
24 changes: 15 additions & 9 deletions src/Application/Http.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,12 @@ public function mapOperatingSystem(callable $map): self
*/
public function service(string|Service $name, callable $definition): self
{
$container = $this->container;

return new self(
$this->os,
$this->env,
fn(OperatingSystem $os, Environment $env) => ($this->container)($os, $env)->add(
static fn(OperatingSystem $os, Environment $env) => $container($os, $env)->add(
$name,
static fn($service) => $definition($service, $os, $env),
),
Expand Down Expand Up @@ -188,18 +190,20 @@ public function appendRoutes(callable $append): self
*/
public function mapRequestHandler(callable $map): self
{
$previous = $this->mapRequestHandler;

return new self(
$this->os,
$this->env,
$this->container,
$this->routes,
fn(
static fn(
RequestHandler $handler,
Container $container,
OperatingSystem $os,
Environment $env,
) => $map(
($this->mapRequestHandler)($handler, $container, $os, $env),
$previous($handler, $container, $os, $env),
$container,
$os,
$env,
Expand All @@ -226,23 +230,25 @@ public function notFoundRequestHandler(callable $handle): self
public function run($input)
{
$container = ($this->container)($this->os, $this->env)->build();
$os = $this->os;
$env = $this->env;
$routes = Sequence::lazyStartingWith($this->routes)
->flatMap(static fn($routes) => $routes)
->map(fn($provide) => $provide(
->map(static fn($provide) => $provide(
Routes::lazy(),
$container,
$this->os,
$this->env,
$os,
$env,
))
->flatMap(static fn($routes) => $routes->toSequence());
$router = new Router(
$routes,
$this->notFound->map(
fn($handle) => fn(ServerRequest $request) => $handle(
static fn($handle) => static fn(ServerRequest $request) => $handle(
$request,
$container,
$this->os,
$this->env,
$os,
$env,
),
),
);
Expand Down
3 changes: 2 additions & 1 deletion src/Http/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,11 @@ public function __construct(Sequence $routes, Maybe $notFound)
public function __invoke(ServerRequest $request): Response
{
$match = new RequestMatcher($this->routes);
$notFound = $this->notFound;

return $match($request)
->map(static fn($route) => $route->respondTo(...))
->otherwise(fn() => $this->notFound)
->otherwise(static fn() => $notFound)
->match(
static fn($handle) => $handle($request),
static fn() => Response::of(
Expand Down
10 changes: 6 additions & 4 deletions src/Middleware/LoadDotEnv.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ private function __construct(Path $folder)

public function __invoke(Application $app): Application
{
$folder = $this->folder;

return $app->mapEnvironment(
fn($env, $os) => $os
static fn($env, $os) => $os
->filesystem()
->mount($this->folder)
->mount($folder)
->get(Name::of('.env'))
->keep(Instance::of(File::class))
->match(
fn($file) => $this->add($env, $file),
static fn($file) => self::add($env, $file),
static fn() => $env,
),
);
Expand All @@ -48,7 +50,7 @@ public static function at(Path $folder): self
return new self($folder);
}

private function add(Environment $env, File $file): Environment
private static function add(Environment $env, File $file): Environment
{
/** @psalm-suppress InvalidArgument Due to the empty sequence in the flatMap */
return $file
Expand Down

0 comments on commit e8311ae

Please sign in to comment.