We'd lose more useful coverage and spend more effort keeping these
accurate through refactors etc than is worth the theoretically "bad"
accidental coverage. Plus, even then we still very often forget to
update these and waste time digging into seemingly uncovered code
and either write duplicate test or discover they are already covered.
Especially for private methods this can be a flawed endavour as
we tend to trust tests when changing those and thus feel we shouldn't
update tests, except it's riddled with private method mentions for
coverage purposes (not in terms of actual called code).
I think the best practice is to write good narrow unit tests,
not to write bad tests and then hide their coverage. Generally
that's what we do. Maybe these are useful when invoking a huge
legacy class, but generally we don't need these I think, at least
in the libs our team maintains.
Change-Id: I4c7d826c7ec654b9efa20778c46c498784661f1c
String offsets in MariaDB are 1-based, except in "Oracle compatible"
mode. SUBSTR(modtoken,0,13) was always the empty string and so the
modtoken comparison was always true. I was able to reproduce a failure
to reach consistency using ring replication.
Add regression test.
Bug: T315271
Change-Id: I74e54e8aba44505dd04426c12d91a9ea0de17f22
Instead of non-blocking I/O, use the "noreply" option instead.
Per benchmark results and code investigation at T310662,
switching off Memcached::OPT_BUFFER_WRITES or Memcached::OPT_NO_BLOCK
causes libmemcached to drop any open connections, incurring a latency
penalty when such methods are called in a loop.
So, use the "noreply" option instead. Without OPT_NO_BLOCK, this is
becomes a single sendto() syscall, and it doesn't block until the TCP
window fills up.
Theoretically OPT_NO_BLOCK could be faster if a setMulti() fills up the
TCP window for many servers, since in blocking mode the client might
not be able to keep all the TCP buffers full. But it would have to be
used with a dedicated connection, so it's an optimisation only suited
for a special case.
Change-Id: I11e3b9394821fd6dcc5c1adb42bb546659ed5af8
In incrWithInit(), when the WRITE_BACKGROUND flag is set, return
true on success, don't try to return the new value. Use the noreply
option to avoid waiting for a response.
assertEquals(3, true) unexpectedly succeeds, so use assertSame() in the
relevant tests. Fix the type of the incr() return value in
MemcachedClient, was string.
Bug: T310662
Change-Id: I1a41255c304b1ac2b6086e7820390c3cbad2e789
Avoid paratest race conditions with multiple memcached classes using
the local server.
Bug: T50217
Change-Id: If88b9431d7c6dd7191ce35b64a6c743f93ea2b43
* Add BagOStuffTest subclasses for all core BagOStuff subclasses,
replacing PHPUNIT_USE_BAGOSTUFF, as suggested in a todo comment.
* Add config $wgEnableRemoteBagOStuffTests which causes all tests
enabled by $wgObjectCache to execute, which means that the memcached
tests are executed by default.
I have verified all except RESTBagOStuff and WinCacheBagOStuff. The
memcached tests fail against memcached 1.5.x but pass against memcached
1.6.x.
Bug: T90875
Change-Id: Id74b5226669f8cb857f859fbc35bc58ab001e873
The new style of checking for the last error during a section of
calls is more robust since it allows nesting of callers. Typically,
an external caller will want to watch a section of code that will
involve zero or more internally watched sections. Errors that are
seen internally (leading to a failing response) should also be
visible externally.
Replace internal BagOStuff clearLastError() calls.
Replace WANObjectCache clearLastError() calls. Such a class should not
clear the error codes since the class is effectively "internal". Callers
that are more meaningfully "external" might want to check the errors.
Cleanup "last" error handling for proxy backends.
Change-Id: I281817a85602967c0ec2bdd23a5d8be101680b64
Add a multi-primary mode option that supports MySQL DB setups
that use circular replication with STATEMENT formatted binlogs.
The `modtoken` column is only used when multi-primary mode is
explicitly enabled in configuration. The column is used by write
queries to determine the "winning" version of keys, with the goal
of approximating "Last-Write-Wins" eventual consistency.
Writes with different timestamps can be handled by picking the
one with the highest timestamp as the "winner". Writes with the
same timestamp, from different primary DBs, can be handled by
picking the one from the primary DB with the highest server_id.
Writes with the same token timestamp from the same primary DB can
be handled by picking the last write to appear in the binlog.
The delete() operation uses tombstones in multi-primary mode,
since there must be a key version to actually compare with the
versions from other operations.
Also:
* Remove "LOCK IN SHARE MODE" that was made obsolete by the
CONN_TRX_AUTOCOMMIT flag. For the SQLite transaction case,
it is serializable anyway.
* Simplified handleWriteError() to match handleReadError()
and merged them into handleDBError().
Changes from d56a686f83:
* Keep using replace() for set() in non-multi-primary mode.
* Fix old encoding issues when incrementing keys with postgres.
Bug: T274174
Change-Id: I25b1278586f99fdace8f2a081f6f460f734e5d83
Empty leading components should still be colon separated. Although the
keyspace and collection should never be empty strings, it does not hurt
to handle that case anyway for safety.
Change-Id: Ic89acaf1fe5c34e58323b2913a9a26f973868590
Add a multi-primary mode option that supports MySQL DB setups
that use circular replication with STATEMENT formatted binlogs.
The `modtoken` column is only used when multi-primary mode is
explicitly enabled in configuration. The column is used by write
queries to determine the "winning" version of keys, with the goal
of approximating "Last-Write-Wins" eventual consistency.
Writes with different timestamps can be handled by picking the
one with the highest timestamp as the "winner". Writes with the
same timestamp, from different primary DBs, can be handled by
picking the one from the primary DB with the highest server_id.
Writes with the same token timestamp from the same primary DB can
be handled by picking the last write to appear in the binlog.
The delete() operation uses tombstones in multi-primary mode,
since there must be a key version to actually compare with the
versions from other operations.
Also:
* Remove "LOCK IN SHARE MODE" that was made obsolete by the
CONN_TRX_AUTOCOMMIT flag. For the SQLite transaction case,
it is serializable anyway.
* Simplified handleWriteError() to match handleReadError()
and merged them into handleDBError().
Bug: T274174
Change-Id: Icc5eff9a032dd3403b5718058f20e38f8ea84af5
Add "generic" key methods for quickly deriving keys from
key component lists in a bijective manor. This is useful
for BagOStuff classes that wrap other BagOStuff instances
or for parsing keys to get stats.
Make the proxy BagOStuff classes (ReplicatedBagOStuff,
MultiWriteBagOStuff, CachedBagOStuff) use "generic" keys
so that they can convert to appropriate keys when making
backing cache instance method calls.
Make EmptyBagOStuff, HashBagOStuff, APCUBagOStuff,
RedisBagOStuff, and RESTBagOStuff use "generic" keys rather
than those of MediumSpecificBagOStuff::makeKeyInternal().
This lets proxy BagOStuff classes bypass key conversions
when used with instances of these classes as backing stores.
Also:
* Fix missing incr(), incrWithInit(), and decr() return
values in MultiWriteBagOStuff.
* Make MultiWriteBagOfStuff, ReplicatedBagOStuff, and
CachedBagOStuff use similar backend method forwarding
styles by using a new BagOStuff method.
* Improved various related bits of documentation.
Bug: T250239
Bug: T235705
Change-Id: I1eb897c2cea3f5b756dd1e3c457b7cbd817599f5
This makes User::pingLimiter() include the expiry time in the payload of
the cache key that holds the current count. This allows us to ignore
stale counts.
Until now, we have been relying on the cache implementation to expire
the relevant keys in time. This however seems to fail sometimes.
Bug: T246991
Change-Id: Ifa3c558b4449f1ca133d0064781f26ac1bf59425
The name change happened some time ago, and I think its
about time to start using the name name!
(Done with a find and replace)
My personal motivation for doing this is that I have started
trying out vscode as an IDE for mediawiki development, and
right now it doesn't appear to handle php aliases very well
or at all.
Change-Id: I412235d91ae26e4c1c6a62e0dbb7e7cf3c5ed4a6
Create a simple APCUBagOStuff subclass and also fix
APCUBagOStuff::incrWithInit() default $init value.
Change-Id: If84963fe7dcfedd6edebfb8785235263e0868ece