Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:111643 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 81740 invoked from network); 20 Aug 2020 03:59:10 -0000 Received: from unknown (HELO php-smtp4.php.net) (45.112.84.5) by pb1.pair.com with SMTP; 20 Aug 2020 03:59:10 -0000 Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 0E0771804DA for ; Wed, 19 Aug 2020 20:00:43 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on php-smtp4.php.net X-Spam-Level: ** X-Spam-Status: No, score=2.3 required=5.0 tests=BAYES_40,BODY_8BITS, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, FREEMAIL_REPLYTO,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, SPF_HELO_NONE,SPF_PASS autolearn=no autolearn_force=no version=3.4.2 X-Spam-Virus: No X-Envelope-From: Received: from mail-vs1-f41.google.com (mail-vs1-f41.google.com [209.85.217.41]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-256) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Wed, 19 Aug 2020 20:00:42 -0700 (PDT) Received: by mail-vs1-f41.google.com with SMTP id n25so411132vsq.6 for ; Wed, 19 Aug 2020 20:00:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:reply-to:from:date:message-id :subject:to:cc; bh=/yVCfpbQDRjMhbDGrqnYqdWlJ7SujRaO4hF9WwF3tFA=; b=SW2B1LNE34DtJ/yhSFiSiX+4AQdViJ4bog/xetDFxU08jMHKNSD0/I+FKkaAAQKuI/ OclDw/izTY4A7EY0ZFKb1uOmidfN8EV2IbQuA4+y88R/mS6hVMQRU/84fpfxDSwhxpeH HEmmsavJJdgDf8F6XnHhwe2c8Uhf9m5FxGXu9mVYcdixWHXZhUnKlTCZBAPdIcFwU9mR FwIdqV+mzzRfEt9PxnUvghyAAfeN+NsXq2RTchFN2eom/xbsW+D6NShQlpqmrH72nen/ e+TMiY4puTiEwOXGo8xhPBn+6MHDmk7GdtdKzzmzWhnX3d3otvOCUhjFKZNVyEHKcIkb +PAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:reply-to :from:date:message-id:subject:to:cc; bh=/yVCfpbQDRjMhbDGrqnYqdWlJ7SujRaO4hF9WwF3tFA=; b=Vk2xMpvohVYHLLs3SgC0CllBuptMUbuYgnZw+SpDpY6y4aCzD28mLq41v8xoJa3N+0 WArxUgT51hle43y3T7RwEo/ECK/+HbvfEyWKruVx09/rebBK0b8NwzzP8aeZM8gVlO5C oNmjcwgAGsb+heS/Din3/ao78UHDDWBcQbqsn9YC2imXUnf+CY5JVZnOly/0H74mX8eH P2b6MHEfi+U+SHcJWyYzLVhufgvNzcAnL5DjqgbNzfmY/eC4kPRVQRX+SD/DslIyditz XXHewO92LZWBuu/DlnozcdJVEmCE/wHpDr1Vzz7fZaetCavnndpm6Re2H8HASzTSDhhP bgQA== X-Gm-Message-State: AOAM53328yI8/xZYDIsy3Owzbr+IBfyhypDdZ4lfvqgKtwJNSjbB1c1o F8pexUjnz/DYJ0UPc5PwZwR3xRRHkkyl0j0fBFM= X-Google-Smtp-Source: ABdhPJzL6PYB+ikE0qVwKD7pam05aZDUgFBJBIiodxCDBL3b4nl9R4uHSEj11uGEX3tE2mQhPtewBT69zULXt17VTlw= X-Received: by 2002:a67:33d3:: with SMTP id z202mr812871vsz.130.1597892440638; Wed, 19 Aug 2020 20:00:40 -0700 (PDT) MIME-Version: 1.0 References: In-Reply-To: Reply-To: erictnorris@gmail.com Date: Wed, 19 Aug 2020 23:00:24 -0400 Message-ID: To: twosee Cc: PHP internals Content-Type: multipart/alternative; boundary="0000000000005049bf05ad465375" Subject: Re: [PHP-DEV] Proposal: Add PDO::checkLiveness method From: eric.t.norris@gmail.com (Eric Norris) --0000000000005049bf05ad465375 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hey Twosee, Thanks for following up! > checkLiveness() is not cost-free, it will also cause redundant system call overhead, In fact, it has been heavily abused. I noticed that many PHP network programming implementations do not care about the overhead of system calls, such as constantly using recv(MSG_PEEK) to check the connection before new requests, this is how checkLiveness() works. This will cause severe performance degradation because failure is always unexpected. I would assume that this overhead is negligible compared to the cost of retrying a failed query - especially for the times when a query cannot be safely retried. That being said, making the method available for folks to use doesn't force them to use it :). An application developer can weigh the tradeoffs for their use-case. > And it even can't guarantee that the next call is successful, the connection may be reset after check. > What can you do if you noticed that the connection is disconnected? phpredis checks the connection before each request and tries to reconnect because the redis connection is almost stateless. So in phpredis, it makes some sense to do so (phpredis will retry 10 times when the connection is down, but this may be bad when the server is busy). Absolutely! As I mentioned in the GitHub pull request thread, checkLiveness does not guarantee the next call is successful, but it *can* tell you if the next call will *definitely* fail without reconnecting. I think that would be a worthwhile check, considering that it costs roughly a syscall to do so. If checkLiveness returns false, your database code would simply reconnect without potentially having to throw an exception (in the case of a non-retryable query) and may end up being a better experience for a hypothetical web user. > All in all, let it fail and try again, the overall performance will be better than checking before calling it every time, so I don't think this API is necessary. > Please don't use it, it will only make your program worse. To be clear, I am not suggesting that developers call checkLiveness before *every* query, I agree that would likely be unnecessary. Where it can be useful though is for checking long-lived connections after some period of inactivity, much like how PDO checks the connection state via check_liveness before reusing a persistent connection (see https://github.com/php/php-src/blob/22982eee339c4983c87cea5d59aaf48601ad703= 0/ext/pdo/pdo_dbh.c#L317-L331). My PR makes it so that you can do the *very thing that PDO does*, but application side. I disagree that this makes your program worse, if so, why should PDO do the same thing? On Sat, Aug 15, 2020 at 10:38 AM twosee wrote: > > > 2020=E5=B9=B48=E6=9C=8815=E6=97=A5 =E4=B8=8A=E5=8D=882:16=EF=BC=8CEric = Norris =E5=86=99=E9=81=93=EF=BC=9A > > > > Hey internals, > > > > I've submitted https://github.com/php/php-src/pull/5935 as a way to > expose > > an underlying PDO driver's check_liveness function to userland scripts. > > Often advice given on the internet is to issue a no-op statement (e.g. > > SELECT 1 FROM dual), but this adds potentially unnecessary overhead and > > latency. Using the PDO driver's check_liveness function offers a > lower-cost > > way of ensuring the connection is still alive. > > > > As noted in the PR, I am not tied to the method name, and open to any > > suggestions to making the PR better - I'm mostly interested in the > > underlying concept. > > > > It appears the test I added is currently failing for pgsql. I didn't > have a > > test setup for that on hand but will look into it if there is positive > > feedback for this PR. > > > > Relatedly, I've also submitted https://github.com/php/php-src/pull/5947 > as > > a way to potentially improve the mysqlnd driver's check_liveness > function. > > > > Thanks! > > > > Eric Norris > > Hi, I am the author of Swoole (https://github.com/swoole/swoole-src), I > have a little network programming experience, the following is my persona= l > opinion: > > I suggest not to check it, let it throw an exception (PHP8 has used > exceptions as the default error reporting way). > > checkLiveness() is not cost-free, it will also cause redundant system cal= l > overhead, In fact, it has been heavily abused. I noticed that many PHP > network programming implementations do not care about the overhead of > system calls, such as constantly using recv(MSG_PEEK) to check the > connection before new requests, this is how checkLiveness() works. This > will cause severe performance degradation because failure is always > unexpected. > > And it even can't guarantee that the next call is successful, the > connection may be reset after check. > > What can you do if you noticed that the connection is disconnected? > phpredis checks the connection before each request and tries to reconnect > because the redis connection is almost stateless. So in phpredis, it make= s > some sense to do so (phpredis will retry 10 times when the connection is > down, but this may be bad when the server is busy). > > But MySQL can't do this, the context of it is too complex, let it throw a= n > exception, catch it, and start from the beginning again is the best and > cheapest way to solve it. > > All in all, let it fail and try again, the overall performance will be > better than checking before calling it every time, so I don't think this > API is necessary. > > Please don't use it, it will only make your program worse. > > Regards, > Twosee > > --0000000000005049bf05ad465375--