elastic / elasticsearch-php

Official PHP client for Elasticsearch.
https://www.elastic.co/guide/en/elasticsearch/client/php-api/current/index.html
MIT License
5.25k stars 964 forks source link

Segmentation Error while using bulk method to update documents #1320

Closed iriteshkumarmishra closed 1 year ago

iriteshkumarmishra commented 1 year ago

Summary of problem or feature request

I get Segmentation fault (core dumped) error when I call bulk (_bulk API) method to update documents inside bref (https://bref.sh/) serverless running in AWS lambda function.

When I call the bulk method, when the code is running on normal linux servers then I don't see any issue. But when I run the same API in lambda then I see this segmentation error. It should not throw any error because same API is being called with same set of data. To fix it, I tried removing the library bulk() function and created a normal guzzle request to ES _bulk API and it is working fine without any errors in lambda. My request is that it should not throw segmentation fault. I checked there were no memory leakage in my code, only just bulk() method call.

Code snippet of problem

use Elasticsearch\ClientBuilder;
// inside class code
$this->clientBuilder = (ClientBuilder::create()->setHosts(['host'])
            ->setBasicAuthentication('username', 'passwd')
            ->build());
// $params is just an array to update documents
$response = $this->clientBuilder->bulk($params); // this line is causing the error

System details

ezimuel commented 1 year ago

@iriteshkumarmishra that's very strange. There's nothing special in the bulk() function. Did you try to use PHP 8.1 or 8.2? I'll try to reproduce the issue using bref with your code example.

iriteshkumarmishra commented 1 year ago

Hello @ezimuel No, I haven’t tried it with php 8.1 or 8.2 I saw the code of bulk method and seems like internally it is creating temp file for the request data. I might be wrong but I think the error is happening because of this temp files.

ezimuel commented 1 year ago

@iriteshkumarmishra here the code of the bulk() function. No file is created. That's why I said it's strange. Here the documentation of the bulk() function and here an example of the bulk() usage.

iriteshkumarmishra commented 1 year ago

@ezimuel This createRequest method is creating stream (here) for the body we gave to the bulk method. The stream is being created using Nyholm\Psr7\Factory\Psr17Factory class' createStream() method. Inside createStream method you can see create() method in which there is temporary file being opened.

public function createStream(string $content = ''): StreamInterface
    {
        return Stream::create($content);
    }

// Inside the create method
public static function create($body = ''): StreamInterface
    {
        if ($body instanceof StreamInterface) {
            return $body;
        }

        if (\is_string($body)) {
            $resource = \fopen('php://temp', 'rw+');
            \fwrite($resource, $body);
            \fseek($resource, 0);
            $body = $resource;
        }

        if (!\is_resource($body)) {
            throw new \InvalidArgumentException('First argument to Stream::create() must be a string, resource or StreamInterface');
        }

        return new self($body);
    }

Hope this helps. Please let me know if I am mistaken here and looking at wrong direction. Thanks

ezimuel commented 1 year ago

@iriteshkumarmishra I see the issue is in the nyholm/psr7 library. I suggest to open an issue in this repository, with a link to the issue opened here.