Close flushes outstanding WAL writes to replicas, releases the read lock, and closes the database. If Done is set, closing it interrupts the shutdown sync retry loop and cancels any in-flight sync attempt.
(ctx context.Context)
| 765 | // and closes the database. If Done is set, closing it interrupts the shutdown |
| 766 | // sync retry loop and cancels any in-flight sync attempt. |
| 767 | func (db *DB) Close(ctx context.Context) (err error) { |
| 768 | db.cancel() |
| 769 | db.wg.Wait() |
| 770 | |
| 771 | db.execMu.Lock() |
| 772 | defer db.execMu.Unlock() |
| 773 | |
| 774 | // Perform a final db sync, if initialized. |
| 775 | if db.db != nil { |
| 776 | if e := db.syncLocked(ctx); e != nil { |
| 777 | err = e |
| 778 | } |
| 779 | } |
| 780 | |
| 781 | // Ensure replicas perform a final sync and stop replicating. |
| 782 | if db.Replica != nil { |
| 783 | if db.db != nil { |
| 784 | if e := db.syncReplicaWithRetry(ctx); e != nil && err == nil { |
| 785 | err = e |
| 786 | } |
| 787 | } |
| 788 | db.Replica.Stop(true) |
| 789 | } |
| 790 | |
| 791 | // Release the read lock to allow other applications to handle checkpointing. |
| 792 | if db.rtx != nil { |
| 793 | if e := db.releaseReadLock(); e != nil && err == nil { |
| 794 | err = e |
| 795 | } |
| 796 | } |
| 797 | |
| 798 | db.mu.Lock() |
| 799 | sqlDB := db.db |
| 800 | f := db.f |
| 801 | db.db = nil |
| 802 | db.f = nil |
| 803 | db.opened = false |
| 804 | db.rtx = nil |
| 805 | db.mu.Unlock() |
| 806 | |
| 807 | if sqlDB != nil { |
| 808 | if e := sqlDB.Close(); e != nil && err == nil { |
| 809 | err = e |
| 810 | } |
| 811 | } |
| 812 | |
| 813 | if f != nil { |
| 814 | if e := f.Close(); e != nil && err == nil { |
| 815 | err = e |
| 816 | } |
| 817 | } |
| 818 | |
| 819 | return err |
| 820 | } |
| 821 | |
| 822 | // syncReplicaWithRetry attempts to sync the replica with retry logic for shutdown. |
| 823 | // It retries until success, timeout, or context cancellation. If db.Done is non-nil, |