101 lines
3.6 KiB
Markdown
101 lines
3.6 KiB
Markdown
# DBConnection
|
|
|
|
Database connection behaviour and database connection pool designed for
|
|
handling transaction, prepare/execute, cursors and client process
|
|
describe/encode/decode.
|
|
|
|
Examples of using the `DBConnection` behaviour are available in
|
|
`./examples/db_agent/` and `./examples/tcp_connection/`.
|
|
|
|
There is also [a series of articles on building database adapters](http://blog.plataformatec.com.br/2018/11/building-a-new-mysql-adapter-for-ecto-part-i-hello-world/). It includes articles covering both DBConnection and Ecto integrations.
|
|
|
|
## Contributing
|
|
|
|
Run unit tests with:
|
|
|
|
$ mix test
|
|
|
|
To run the integration tests (for each available pool):
|
|
|
|
$ mix test.pools
|
|
|
|
To run all tests:
|
|
|
|
$ mix test.all
|
|
|
|
## Design
|
|
|
|
This library is made of four main modules:
|
|
|
|
* `DBConnection` - this is the code running on the client
|
|
and the specification of the DBConnection API
|
|
|
|
* `DBConnection.Connection` - this is the process that
|
|
establishes the database connection
|
|
|
|
* `DBConnection.ConnectionPool` - this is the connection
|
|
pool. A client asks the connection pool for a connection.
|
|
There is also an ownership pool, used mostly during tests,
|
|
which we won't discuss here.
|
|
|
|
* `DBConnection.Holder` - the holder is responsible for
|
|
keeping the connection and checkout state. It is modelled
|
|
by using an ETS table.
|
|
|
|
Once a connection is created, it creates a holder and
|
|
assigns the connection pool as the heir. Then the holder
|
|
is promptly given away to the pool. The connection itself
|
|
is mostly a dummy. It is there to handle connections and pings.
|
|
The state itself (such as the socket) is all in the holder.
|
|
|
|
Once there is a checkout, the pool gives the holder to the
|
|
client process and stores all relevant information in the
|
|
holder table itself. If the client terminates without
|
|
checking in, then the holder is given back to the pool via
|
|
the heir mechanism. The pool will then discard the connection.
|
|
|
|
One important design detail in DBConnection is that it avoids
|
|
copying data. Other database libraries would send a request
|
|
to the connection process, perform the query in the connection
|
|
process, and then send it back to the client. This means a lot of
|
|
data copying in Elixir. DBConnection keeps the socket in the
|
|
holder and works on it directly.
|
|
|
|
DBConnection also takes all of the care necessary to handle
|
|
failures, and it shuts down the connection and the socket
|
|
whenever the client does not check in the connection to avoid
|
|
recycling sockets/connections in a corrupted state (such as a socket
|
|
that is stuck inside a transaction).
|
|
|
|
### Deadlines
|
|
|
|
When a checkout happens, a deadline is started by the client
|
|
to send a message to the pool after a time interval. If the
|
|
deadline is reached and the connection is still checked out,
|
|
the holder is deleted and the connection is terminated. If the
|
|
client tries to use a terminated connection, an error will
|
|
be raised (see `Holder.handle/4`).
|
|
|
|
### Pool
|
|
|
|
The queuing algorithm used by the pool is [CoDel](https://queue.acm.org/appendices/codel.html)
|
|
which allows us to plan for overloads and reject requests
|
|
without clogging the pool once checkouts do not read a certain
|
|
target.
|
|
|
|
## License
|
|
|
|
Copyright 2015 James Fish
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|