Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Changes to support Edge Server [API] #2202

Open
wants to merge 62 commits into
base: master
Choose a base branch
from
Open

Changes to support Edge Server [API] #2202

wants to merge 62 commits into from

Conversation

snej
Copy link
Collaborator

@snej snej commented Jan 8, 2025

This branch contains all the LiteCore enhancements & fixes needed to implement Edge Server.

IMPORTANT: There are also changes in the EE repo: https://github.com/couchbase/couchbase-lite-core-EE/pull/47

  • Removed the REST server code, and a few support classes like RequestResponse; that's now in Edge Server.
  • Modified RESTSyncListener to avoid using RequestResponse, which simplified the code. (That's in the EE repo.)
  • The replicator now uses the new DatabasePool. By default, DBAccess will create its own pool of size 1, but an alternate Replicator constructor gives an existing shared pool for it to use. This will greatly reduce the overhead of running lots of replicators at once.
  • More stuff, described in the individual commits.

C API Changes:

  • ⚠️ Removed C4ListenerAPIs type
  • ⚠️ Removed apis field from C4ListenerConfig, as well as fields specific to REST APIs, like directory`
  • ⚠️ Removed c4listener_availableAPIs()
  • ⚠️ Removed api parameter from c4listener_getURLs()
  • Added serverName and serverVersion fields to C4ListenerConfig; you can leave them NULL
  • Added c4listener_shareDBWithConfig() and C4ListenerDatabaseConfig struct, for db-specific configuration

C++ API Changes:

  • ⚠️ Removed C4Listener::availableAPIs()
  • ⚠️ Removed api parameter from C4Listener::URLs()
  • Added optional C4ListenerDatabaseConfig const* parameter to C4Listener::shareDB()
  • Added C4Collection::getPurgeCount()
  • Added C4Database::Transaction::isActive()
  • Added a C4DocEnumerator constructor that takes a startKey parameter.
  • Added C4Query::parameterNames()
  • Added [[nodiscard]] and/or LIFETIMEBOUND attributes to some methods. These will intentionally trigger warnings in buggy code; if so, look carefully and fix your code!

@snej
Copy link
Collaborator Author

snej commented Jan 8, 2025

Jenkins builds are failing due to a CMake error:

[2025-01-08T18:54:13.724Z] CMake Error at cmake/platform_linux.cmake:75 (target_link_libraries):
[2025-01-08T18:54:13.724Z]   Target "LiteCoreObjects" links to:
[2025-01-08T18:54:13.724Z] 
[2025-01-08T18:54:13.724Z]     icu::icu4c
[2025-01-08T18:54:13.724Z] 
[2025-01-08T18:54:13.724Z]   but the target was not found.  Possible reasons include:

@snej
Copy link
Collaborator Author

snej commented Jan 8, 2025

Ubuntu in GitHub CI is failing a test due to a runtime exception:

DB Info SQLite message: statement aborts at 36: [CREATE UNIQUE INDEX IF NOT EXISTS "kv_.loopback.test_seqs" ON "kv_.loopback.test" (sequence)] attempt to write a readonly database

I know how to fix this...

@cbl-bot
Copy link

cbl-bot commented Jan 9, 2025

Code Coverage Results:

Type Percentage
branches 66.11
functions 78.1
instantiations 70.23
lines 77.36
regions 73.18

@snej
Copy link
Collaborator Author

snej commented Jan 9, 2025

Jenkins failures:

macOS: The code coverage script push_coverage_results.py blew up somehow. No idea why.

Windows: Test "Continuous Super-Fast Push" failed, due to a DatabasePool deadlock:

[2025-01-09T01:48:20.321Z] Default ERROR LiteCore throwing LiteCore error 16: Timed out waiting on DatabasePool::borrow
[2025-01-09T01:48:20.321Z] 	at litecore::DatabasePool::borrow in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\LiteCore\Support\DatabasePool.cc: line: 183: address: 0x7FF6B4B7EB50
[2025-01-09T01:48:20.321Z] 	at litecore::DatabasePool::borrow in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\LiteCore\Support\DatabasePool.cc: line: 187: address: 0x7FF6B4B7E7E0
[2025-01-09T01:48:20.321Z] 	at litecore::repl::DBAccess::useCollection in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\DBAccess.hh: line: 52: address: 0x7FF6B4ABA7A0
[2025-01-09T01:48:20.321Z] 	at litecore::repl::ChangesFeed::shouldPushRev in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\ChangesFeed.cc: line: 220: address: 0x7FF6B4AB42B0
[2025-01-09T01:48:20.321Z] 	at litecore::repl::ChangesFeed::shouldPushRev in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\ChangesFeed.cc: line: 209: address: 0x7FF6B4AB3190
[2025-01-09T01:48:20.321Z] 	at litecore::repl::Pusher::doneWithRev in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\Pusher+Revs.cc: line: 379: address: 0x7FF6B4B30950
[2025-01-09T01:48:20.321Z] 	at litecore::repl::Pusher::sendRevision in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\Pusher+Revs.cc: line: 179: address: 0x7FF6B4B2DE70
[2025-01-09T01:48:20.321Z] 	at litecore::repl::Pusher::maybeSendMoreRevs in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\Pusher+Revs.cc: line: 34: address: 0x7FF6B4B2DD50
[2025-01-09T01:48:20.321Z] 	at litecore::repl::Pusher::handleChangesResponse in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\Pusher.cc: line: 329: address: 0x7FF6B4B167B0
[2025-01-09T01:48:20.321Z] 	at `litecore::repl::Pusher::sendChanges'::`2'::<lambda_1>::operator() in C:\Jenkins\workspace\line_couchbase-lite-core_PR-2202\couchbase-lite-core\Replicator\Pusher.cc: line: 251: address: 

@borrrden
Copy link
Member

borrrden commented Jan 9, 2025

Windows tests appear to be failing now, and linting is needed

@snej snej force-pushed the feature/edge-server branch from 55b1a07 to 2b5a36b Compare January 10, 2025 00:09
@snej snej force-pushed the feature/edge-server branch from ad46321 to 6bd2587 Compare January 22, 2025 22:37
@snej snej changed the title Changes to support Edge Server Changes to support Edge Server [API] Jan 22, 2025
snej added 19 commits January 22, 2025 15:00
- Removed RESTListener
- Misc. internal API additions / changes / fixes
WITH_ERROR can't use Catch's UNSCOPED_INFO(), but I've amended it to
use WARN(), which will also show up in the test results.
If the pool is opened with a read-only db, then borrowWriteable()
should immediately throw NotWriteable, not wait for a db to be
returned and then throw Busy.
c4Replicator+Pool.hh defines factory functions to start a replicator
given a DatabasePool* not a C4Database*.
This shields callers from having to include c4DatabaseImpl.hh etc.,
which drag in a buttload of internal replicator headers.
Gives Task subclasses more control over when a finished task should
be removed from the listing. Needed for ChangesTask.
snej and others added 29 commits January 22, 2025 15:00
Internally, I streamlined the RecordEnumerator API by folding the
other initialization parameters into the Options struct.
- ICU is now downloaded as part of the build
- No more top level build server CMake wrapper is needed
- LiteCore and LiteCoreStatic targets can be disabled to avoid having needless install output
- Move sTempDir into LogEncoderTest.cc so it can be shared between CppTests and cbl-logtest
for EdgeServer, as part of creating Etags
It caused errors when LITECORE_BUILD_TESTS or LITECORE_BUILD_SHARED
were turned off.
It's a no-op that got left in a commit (27d3530) by accident.
- HTTPLogic::parseHeaders() rejects control characters
- Added constant for status 415
- Proper errors in TCPSocket::readHTTPBody()
The index is created lazily. If a collection doesn't have one, an
operation using a read-only db from the pool might trigger creating
it, which will fail because it's read-only.

To work around this, DBAccess's constructor uses the writeable db
to call call `getDocumentBySequence` on every collection, forcing the
index to be created.
The search for ICU needs to happen on Linux desktop only.  Also, ensure that the BUILD_ENTEPRISE flag is properly set now that we don't use the wrapper CMake project anymore (also on Windows this happened)
and bump compiler version to gcc 11 (required for using cbdeps ICU)
When Pusher::sendRevision() fails, it calls doneWithRev(). Both
methods were borrowing the db from the pool, so the second borrow
deadlocked.
Fixed this by having sendRevision release the db before calling
doneWithRev.

Also added diagnostics to DatabasePool, so when a borrow fails it can
identify which thread(s) are using the database.
If a thread that currently has a read-only BorrowedDatabase calls
borrow() again, the result will now be a BorrowedDatabase on the
_same_ C4Database instance. This doesn't use up any of the other
databases in the pool, so it always succeeds. Previously, this could
cause a deadlock if all the available dbs were used up.

(This is safe because (a) it's on the same thread so there are no
concurrency issues, and (b) it's a read-only db so one caller can't
make changes that would break the other one.)

This eliminates the need for the deadlock workaround I just added
to Pusher+Revs.cc, so I've removed it.
If the keyspace explicitly includes "_default" for the collection
or scope, it would fail to find the C4Collection.
It didn't think the body was JSON if the content-type was
"application/json;charset=utf-8".
Suppresses the following scary lines logged by a TLS server:

ERROR: (TLS) mbedTLS(S): mbedtls_ssl_fetch_input() returned -80 (-0x0050)
ERROR: (TLS) mbedTLS(S): ssl_get_next_record() returned -80 (-0x0050)
ERROR: (TLS) mbedTLS(S): mbedtls_ssl_read_record() returned -80 (-0x0050)
WARNING: (WS) ResponderSocket got POSIX error 54 "Connection reset by peer"
ERROR: (TLS) mbedTLS(S): mbedtls_ssl_flush_output() returned -80 (-0x0050)
ERROR: (TLS) mbedTLS(S): mbedtls_ssl_write_record() returned -80 (-0x0050)
ERROR: (TLS) mbedTLS(S): mbedtls_ssl_send_alert_message() returned -80 (-0x0050)
mbedTLS doesn't seem to like two `mbedtls_ssl_context`s performing
handshakes simultaneously on different threads, using the
same `mbedtls_ssl_config`. It leads to weird RSA private key errors.

Using a mutex in TLSContext makes the problem go away. It's not an
ideal solution; I may find a better fix if I can find mbedTLS docs
on thread-safety.
The proper fix is to enable mbedTLS's thread-safety feature by
defining MBEDTLS_THREADING_C in its config.h.
Even in relatively normal cases, like a client giving up on the
handshake or disconnecting, mbedTLS logs a number of scary-looking
errors. It's best to just downgrade all the messages from its
logging callback to Info or below.
@snej snej force-pushed the feature/edge-server branch from 6bd2587 to 219a0c1 Compare January 22, 2025 23:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants