While the default library suffices for small-scall WebDAV installations, there are areas that can be optimized for maximum performance, and operations in a load-balanced environment.
This manual aims to cover the most important bits.
All operations are done on Nodes managed by the
Tree class. In order for the
ObjectTree to find the nodes, it must traverse the entire tree.
You should optimize
getChild() in your nodes as much as
possible to accomodate for it.
You can avoid traversing the tree by subclassing
childExists with your own methods.
If this really helps you highly depends on your situation. Profile first, optimize after.
Move and Copy
Move and Copy operations can be slow, especially when moving/copying bigger objects.
Each of these methods traverses the entire tree, and operates on them one-by-one, as an example, a move of a directory follows the following pattern:
- The Tree tranverses the entire source tree, for each item it will
- do a get() on the source file, and a createFile on the destination (heavy)
- make subdirectories if directories are encountered
- copy all the properties over in a similar fashion (if IProperties is used)
- Next, (if it was a move operation) it will traverse the entire source tree again, deleting all files and directories one-by-one
It's possible to optimize
move a great deal by implementing
Sabre\DAV\IMoveTarget. This interface allows a collection to 'receive' a
node that's being moved.
There's currently not an equivalent for
copy, because moves are typically
an operation that can be optimized in a lot of systems if it's a simple
'rename', but this is often not true for copy operations.
To optimize copy, you must subclass the
Tree class and reimplement the
Delete operations might also by default traverse the tree and delete nodes one
by one. If your backend allows it, you might be able to optimize quickly
deleting subtrees simply by making modifications to a Node-specific
If you created your own CalDAV backend, it may make sense to try to optimize
Sabre\CalDAV\Backend\AbstractBackend class provides a
standard implementation, that fetches every object for a calendar and tries to
see if the query filters out the object, or not.
Sabre\CalDAV\Backend\PDO class tries to optimize this, by filtering a
bunch of common queries and directly applying them to the SQL queries.
In some cases it's confident enough to know that no further iCalendar parsing is needed to figure out the final results.
It is also recommended to make sure that your
getCalendarObjects method does
not return the iCalendar object, but it does return the 'size' and 'etag'
This allows the server to not have to fetch the objects at all for certain large operations, which can save a lot of memory.
If you use CalDAV, CardDAV or WebDAV-Sync operations, the server often has to access many nodes by name.
This can be optimized by nodes by implementing the
interface. This is implemented by default by the CalDAV and CardDAV backends.
Load Balanced SabreDAV
SabreDAV has a few standard utilities for locking and catching 'temporary
files'. These classes (
Sabre\DAV\Locks\Backend\File) store information on the filesystem.
It would be possible to store these files on a network location instead, as long as the network filesystem has proper support for flock() (which NFS as an example doesn't).
The Locks backend in particular also comes in a
flavour, which can store locks in MySQL or PostgreSQL database.
Currently 'temporary files' don't get cleaned up, and a cron job should be made to delete older files (>1 hour).
Read: Working with large files.