Remoto - VFS
|
VFS_node is the base class from which all other VFS_node classes derive. More...
#include <VFS_node.h>
Public Slots | |
virtual void | applyDiff (VFS_request *r) |
Apply a diff received via subscription. More... | |
virtual void | executeRequest (VFS_request *t) |
Based on the VFS_request::requestType, execute the function associated with an operation. More... | |
void | notifySubscribers (VFS_node *origin, VFS_request *t) |
Propagate a diff to subscribers. More... | |
virtual void | receiveResponse (VFS_request *t) |
Once a VFS_request has been completed, a response will be issued back to its _origin. More... | |
void | remove (bool andDelete) |
Remove a child node. More... | |
virtual void | remove (VFS_node *node=nullptr, QString *name=nullptr, QString user="server") |
Remove a child node from this node. More... | |
virtual void | subtreeRequest (VFS_request *t) |
find() the target of a VFS_request, and execute the request More... | |
virtual void | unsubscribeAll (VFS_node *n) |
Remove all references to a subscriber from this node. More... | |
Signals | |
void | diff (VFS_node *origin, VFS_request *t) |
Emit a diff, which will trigger notifySubscribers() for a mounted node. More... | |
void | finished (bool andDelete=false) |
Emitted if a thread fails to create its node, or a node is rm()'d, or any other reason a node has completed its lifecycle. It is deleted if andDelete==true . More... | |
void | mounted () |
Emitted when a node is mount()ed. More... | |
void | unmounted (VFS_node *self) |
Emitted when a node is unmount()ed. More... | |
Public Member Functions | |
Q_INVOKABLE | VFS_node () |
The VFS_node constructor will add its instance to the VFS_node::__allNodes global node registry, observing thread safety rules. More... | |
virtual | ~VFS_node () |
VFS_node destructor. More... | |
virtual VFS_node * | append (QString name, VFS_node *node, bool containerCheck=true, QString user="server") |
Append a VFS_node as a child of this node. More... | |
QString | className () |
Return the class name of a node. More... | |
virtual VFS_request * | createRequest (VFS_request::requestType type, QString path, QString user="unknown", QJsonDocument data=QJsonDocument(), QJsonObject metadata=QJsonObject(), bool dontDelete=false) |
Create a new VFS_request with this object as _origin. More... | |
VFS_node * | find (QString path) |
Find a node by string path. More... | |
virtual VFS_node * | find (VFS_request *r) |
Find a node using a VFS_request. More... | |
VFS_node * | findChildWithName (QString name) |
Check if a child with a given name exists. More... | |
virtual bool | isContainer () |
A VFS_node may have children. More... | |
virtual VFS_node * | mount () |
Mount this node. More... | |
virtual QString | reportDetails () |
Additional details for a generated report. More... | |
QString | uniqueChildName (QString name) |
Generate a unique child name. More... | |
virtual VFS_node * | unmount () |
Unmount this node. More... | |
virtual bool | validChildName (QString name) |
Check if a node name is valid. More... | |
Static Public Member Functions | |
static bool | __isNode (VFS_node *) |
Check to see if a node is in the global registry. More... | |
static QString | code (QString nodename, QString libname, QString &error) |
Fetch code or any other resource from a node. More... | |
Protected Member Functions | |
virtual void | aclDefaults (VFS_request *r) |
Return default values and features associated wth this node. More... | |
void | addACLDefault (QJsonObject &acl, bool value, QString description="") |
Add a default value to the acl object. More... | |
void | addACLFeature (QJsonObject &acl, QString feature, bool value, QString description="") |
Add a feature to the acl object. More... | |
void | addACLFeatureGroup (QJsonObject &acl, QString feature, QString group, bool value) |
Add a feature group to the acl object. More... | |
void | addACLFeatureUser (QJsonObject &acl, QString feature, QString user, bool value) |
Add a feature user to the acl object. More... | |
void | addACLGroup (QJsonObject &acl, QString group, bool value) |
Add a group to the acl object. More... | |
void | addACLUser (QJsonObject &acl, QString user, bool value) |
Add a user to the acl object. More... | |
virtual QByteArray | icon () |
Fetch the icon for a node. More... | |
virtual void | issueRequest (VFS_node *target, VFS_request *t) |
Issue a VFS_request to its target. More... | |
virtual void | issueRequest (VFS_request *t) |
A convenience function. More... | |
virtual void | issueResponse (VFS_request *t) |
Once a request has been completed, issue a response. More... | |
virtual void | ls (VFS_request *r) |
List the contents of this node. More... | |
virtual void | metadata (VFS_request *r) |
Fetch the metadata of this node. More... | |
virtual void | read (VFS_request *r) |
Return the data contents of this node, or if it's a container call ls() More... | |
virtual void | releaseLock (VFS_request *r) |
Release a lock on this node. More... | |
virtual void | report (VFS_request *r) |
Report debugging information about the current state of this node. More... | |
virtual void | requestLock (VFS_request *r) |
Request a lock on this node. More... | |
virtual void | rm (VFS_request *r) |
Remove a child entry from a node, or the node itself. More... | |
virtual void | submit (VFS_request *r) |
Submit a diff to a node. More... | |
virtual void | subscribe (VFS_request *r) |
Add an entry to this node's _subscription list. More... | |
virtual void | unsubscribe (VFS_request *r) |
Remove an entry from this node's _subscription list. More... | |
virtual void | unsubscribePath (QString path) |
Unsubscribe all references to a subpath. More... | |
virtual void | write (VFS_request *r) |
Write data to this node. More... | |
Protected Attributes | |
VFS_children | _children |
This node's children. More... | |
QMutex | _lock |
A recursive mutex that is local to this node. More... | |
VFS_subscriptionType | _subscribers |
This node's subscribers. These subscribers will receive diff notifications. More... | |
Static Private Member Functions | |
static void | __addNode (VFS_node *) |
Add a node to the global registry. More... | |
static bool | __removeNode (VFS_node *) |
Remove a node from the global registry. More... | |
Static Private Attributes | |
static QSet< VFS_node * > | __allNodes |
The static global registry for all exiting nodes, used for thread safety checks. More... | |
static QMutex | __allNodesMutex |
The global registry mutex, which will lock when node creation or deletion is being performed. More... | |
Friends | |
class | VFS_session |
class | VFS_thread |
VFS_node is the base class from which all other VFS_node classes derive.
A VFS_node contains all the necessary apparatus for sending and receiving requests, executing them, managing children, managing subscriptions, notifying subscribers, etc.
The VFS is a tree of VFS_node entries where VFS is the root node.
Definition at line 142 of file VFS_node.h.
|
explicit |
The VFS_node constructor will add its instance to the VFS_node::__allNodes global node registry, observing thread safety rules.
Definition at line 515 of file VFS_node.cpp.
|
virtual |
VFS_node destructor.
__removeNode() from the global registry, and recursively destroy all children.
Because this is modifying the object, it uses the VFS_node::_lock mutex.
Definition at line 531 of file VFS_node.cpp.
|
staticprivate |
Add a node to the global registry.
n | The node to add |
This will lock the static global VFS_node::__allNodesMutex
Definition at line 603 of file VFS_node.cpp.
|
static |
Check to see if a node is in the global registry.
n | The VFS_node to check |
This will lock the static global VFS_node::__allNodesMutex
Definition at line 588 of file VFS_node.cpp.
|
staticprivate |
Remove a node from the global registry.
n | The node to remove |
Definition at line 617 of file VFS_node.cpp.
|
protectedvirtual |
Return default values and features associated wth this node.
r | The VFS_request object |
The un-subclassed case will return { "default":true }
, which will allow access in all cases.
Reimplemented in aclEditor, admin, and sessionsList.
Definition at line 918 of file VFS_node.cpp.
|
protected |
Add a default value to the acl object.
acl | The QJsonObject being used as the ACL |
value | The default value for this VFS_node |
description | An optional description about the ACL entry that appears as a tooltip in the editor |
Note that this modifies the incoming acl object.
Definition at line 2131 of file VFS_node.cpp.
|
protected |
Add a feature to the acl object.
acl | The QJsonObject being used as the ACL |
feature | The feature to add |
value | The default access value for this feature |
description | An optional description that appears as a tooltip in the aclEditor |
Note that this modifies the incoming acl object.
Definition at line 2183 of file VFS_node.cpp.
|
protected |
Add a feature group to the acl object.
acl | The QJsonObject being used as the ACL |
feature | The application feature |
group | The group to add to the feature |
value | The access value for this feature's group list |
Note that this modifies the incoming acl object.
Definition at line 2205 of file VFS_node.cpp.
|
protected |
Add a feature user to the acl object.
acl | The QJsonObject being used as the ACL |
feature | The application feature |
user | The user to add to the feature |
value | The access value for this feature's user list |
Note that this modifies the incoming acl object.
Definition at line 2227 of file VFS_node.cpp.
|
protected |
Add a group to the acl object.
acl | The QJsonObject being used as the ACL |
group | The group name to add |
value | The acces value for the group |
Note that this modifies the incoming acl object.
Definition at line 2148 of file VFS_node.cpp.
|
protected |
Add a user to the acl object.
acl | The QJsonObject being used as the ACL |
user | The user to add |
value | The access value for the user |
Note that this modifies the incoming acl object.
Definition at line 2165 of file VFS_node.cpp.
|
virtual |
Append a VFS_node as a child of this node.
name | The child name |
node | The VFS_node instance pointer |
containerCheck | Normally children can only be added to nodes where isContainer()=true . This is an override. |
user | The user adding the node, used for logging. |
This is the main mechanism for creating a VFS tree.
Reimplemented in VFS_ephemeral, and VFS_thread.
Definition at line 1566 of file VFS_node.cpp.
|
virtualslot |
Apply a diff received via subscription.
r | The VFS_request object |
The base class implementation calls notifySubscribers(), which will re-distribute a diff received from a subscription to this node's subscribers using VFS_node::notifySubscribers().
Subclass implementations may call submit(r), or perform more complex diff operations.
Definition at line 1463 of file VFS_node.cpp.
QString VFS_node::className | ( | ) |
Return the class name of a node.
The class name is fetched from Qt's metaObject(), which is useful for debug logging or fake user strings. Be sure to use the Q_OBJECT in a class definition to populate the metaObject.
Definition at line 2039 of file VFS_node.cpp.
|
static |
Fetch code or any other resource from a node.
nodename | The nodename or namespace for the request |
libname | The library requested |
error | A reference to an error string, for writing errors back to the caller |
The base class implementation returns nothing, and writes an error string to error.
A plugin could choose to load data from disk rather than a Qt resource. This would offer the benefit of not needing to recompile the plugin and restart the server for each change, but with the disadvantage of not having a fully encapsulated distribution package.
Definition at line 1038 of file VFS_node.cpp.
|
virtual |
Create a new VFS_request with this object as _origin.
type | The request type |
path | The request path |
user | The user who is performing the request |
data | The request data |
metadata | The request metadata |
dontDelete | A flag indicating whether the request is to be deleted when complete |
this
set as the _origin.This is a convenience function, as sometimes it's not clear who is the _origin and who is the _receiver of a VFS_request.
Also, this can be subclassed to return a variant of a VFS_request, which is useful for some classes like VFS_remotoserver, who needs to use VFS_remotoserver_request for websocket communication.
The dontDelete flag should be rarely used, and only in cases where an inline VFS_request is being made on the same thread and the result is needed for later operations. Use at your own risk!
Reimplemented in VFS_remotoserver_client.
Definition at line 1913 of file VFS_node.cpp.
|
signal |
Emit a diff, which will trigger notifySubscribers() for a mounted node.
|
virtualslot |
Based on the VFS_request::requestType, execute the function associated with an operation.
t | The VFS_request object |
See the Commands page for a table of these calls.
After the command function is executed, issueResponse() is called if the request does not have a callback.
Definition at line 1809 of file VFS_node.cpp.
VFS_node * VFS_node::find | ( | QString | path | ) |
Find a node by string path.
path | The path, from this VFS_node, to search |
Definition at line 1100 of file VFS_node.cpp.
|
virtual |
Find a node using a VFS_request.
r | The VFS_request object |
The find function has many nuances, especially in the context of complex subclasses. Strictly speaking, the find() method will explode a path, take the first path entry, and search for a child with a matching name. If one is found, this will be repeated on the child.
More complex VFS_node subclasses represent virtual filesystem boundaries, for instance: VFS_thread, VFS_tcp_client, VFS_HD. If a node represents a barrier, it will return itself (this) as the found node, which will result in a path fragment. The expectation is that the node will use the path fragment (r->_path) to complete its operation by redirecting to somewhere else.
For instance, a VFS_HD node will always return itself for find(), and then use the path fragment plus its filesystem prefix to finally have access to a file on a hard disk.
Or, a VFS_thread will always return itself and then issue the request, with the remaining path parts to its _node, which preserves thread safety.
It is not a valid assumption to think that a find() will result in the node type you are interested in. It will often return a node at a filesystem boundary, so therefore typecasting a find() result is usually not possible unless you are sure of the nature of the path being searched.
Reimplemented in logView, VFS_auth, VFS_sessionManager, VFS_acl, VFS_application, VFS_logger, VFS_thread, VFS_datastore, VFS_ephemeral, VFS_QRC, VFS_cron, VFS_tcp_mount, VFS_remotoserver_client, and VFS_threadpool.
Definition at line 1135 of file VFS_node.cpp.
VFS_node * VFS_node::findChildWithName | ( | QString | name | ) |
Check if a child with a given name exists.
name | The name to search |
This is different from VFS_node::find() in that it does not search recursively and does not support meta entries. Only _children is searched by exact name.
Definition at line 2078 of file VFS_node.cpp.
|
signal |
Emitted if a thread fails to create its node, or a node is rm()'d, or any other reason a node has completed its lifecycle. It is deleted if andDelete==true
.
|
protectedvirtual |
Fetch the icon for a node.
Icons are formatted to be placed directly in HTML tags (for instance, the 'src' field of an <img>). Subclasses will want to provide their own icons, or use an entry from VFS_icons. By default, if isContainer()==true
, a folder icon will be returned, otherwise a document icon.
The icon returned should include mime type, encoding, and image data, as specified in RFC 2397.
Reimplemented in aclEditor, admin, cpuUsage, logView, sessionsList, VFS_mongo, VFS, VFS_auth, VFS_session, VFS_sessionManager, VFS_application, VFS_ephemeral, VFS_HD, VFS_cron, VFS_curl, VFS_iframe, VFS_stream, VFS_tcp_export, and VFS_tcp_mount.
Definition at line 655 of file VFS_node.cpp.
|
virtual |
A VFS_node may have children.
This flag determines whether or not they are allowed.
By default, all VFS_nodes are containers.
Generally, this method is overridden in a subclass to return a hardcoded true
or false
depending on the nature of the node.
A node that is a container can append() children, and in directory listings, a container node will appear as a directory.
Reimplemented in aclEditor, cpuUsage, sessionsList, VFS_auth, VFS_session, VFS_acl, VFS_thread, VFS_datastore, VFS_ephemeral, VFS_QRC, VFS_cron, VFS_curl, VFS_pulse, VFS_stream, VFS_httpd, VFS_tcp_client, VFS_tcp_server, VFS_tcp_mount, VFS_udp_socket, VFS_websocket_client, VFS_websocket_server, and VFS_threadpool.
Definition at line 2025 of file VFS_node.cpp.
|
protectedvirtual |
Issue a VFS_request to its target.
target | The target of the request |
t | The VFS_request object |
This will call subtreeRequest() on the target node by calling it as a slot. Thread safety is observed by calling __isNode().
Note that t->_path
should be relative to the target node, not necessarily the VFS::root()
If t->_path==""
, then the target will directly execute the request, because find() will immediately return.
Definition at line 1955 of file VFS_node.cpp.
|
protectedvirtual |
A convenience function.
t | The VFS_request object |
This is equivalent to:
Definition at line 1933 of file VFS_node.cpp.
|
protectedvirtual |
Once a request has been completed, issue a response.
t | The VFS_request object |
This is usually called at the end of executeRequest(), and will issue a payload to the receiveResponse() slot. Thread safety is maintained using __isNode().
Definition at line 1981 of file VFS_node.cpp.
|
protectedvirtual |
List the contents of this node.
r | The VFS_request object |
List format will be:
Where each child is listed with the status of isContainer(). This will allow the receiver to know whether or not a child entry can be recursed.
The assumption is that if isContainer()==false
, the sub-path supports VFS requests like read(), submit(), or subscribe()
Subclasses may choose to list additional virtual children if desired. Those entries will need to be added to find() to be effective.
Reimplemented in google_oauth2, VFS_mongo, VFS_pam, VFS_curlauth, VFS_nopasswd, VFS_passwd, VFS_application, VFS_ephemeral, VFS_HD, VFS_QRC, and VFS_cron.
Definition at line 692 of file VFS_node.cpp.
|
protectedvirtual |
Fetch the metadata of this node.
r | The VFS_request object |
The base implementation will call icon() to populate the r->_metadata["icon"]
field.
Generally, the metadata will want to contain "icon" and "type" fields, but could contain anything. It is recommended that classes call their parent implementation before modifying the metadata:
Reimplemented in aclEditor, admin, cpuUsage, logView, sessionsList, VFS_mongo, VFS_ephemeral, VFS_HD, VFS_QRC, VFS_applications, VFS_curl, VFS_iframe, VFS_stream, and VFS_tcp_server.
Definition at line 797 of file VFS_node.cpp.
|
virtual |
Mount this node.
This will make a signal/slot connection from this::diff to this::notifySubscribers(). The idea is that an unmounted node cannot emit meaningful diffs, as it's not part of the filesystem.
When mount() is called, the node will emit mounted(), which can be a useful trigger for other operations.
A node may choose to subclass this, however the base implementation should always be called.
Reimplemented in VFS_thread.
Definition at line 1718 of file VFS_node.cpp.
|
signal |
Emitted when a node is mount()ed.
|
slot |
Propagate a diff to subscribers.
origin | The VFS_node that the redistributed VFS_requests will use as _origin |
t | The diff VFS_request to redistribute |
Iterate over the _subscribers list, and build a new VFS_request for each subscriber which contains the data from the diff VFS_request. The new VFS_request object is sent to the executeRequest() slot for each subscriber.
If the request's VFS_request::_data and VFS_request::_metadata are both empty, this function will abort, since no meaningful data will be propagated.
Usually if a client calls submit() to a VFS_node that it's already subscribed to, it doesn't need to receive the diff back, because it was the node that originated the request. The VFS_request::_notifyExceptions list keeps track of which subscribers are not to be sent data for this request. This method will check to see if an exception exists, and if so, it will skip that subscriber.
Because VFS_request::_notifyExceptions is public, nodes can be added any time during a request's lifecycle, however this is the only place that the exception is checked and used. Be aware of thread safety when adding notify exceptions!
Definition at line 1497 of file VFS_node.cpp.
|
protectedvirtual |
Return the data contents of this node, or if it's a container call ls()
r | The VFS_request object |
The base class implementation will return no data and _success will be false, except for the case of isContainer()==true
, where ls() will be performed.
Data should be written to VFS_request::_data, and can be any JSON content.
Note that if a pane is subscribing to a node, the VFS_client will close panes that receive null
as content. Even if you plan to do nothing with the read value of a node, you should provide some non-null data to prevent the pane from closing, or failing to open.
Reimplemented in aclEditor, admin, cpuUsage, logView, sessionsList, google_oauth2, VFS_mongo, VFS_pam, VFS_curlauth, VFS_nopasswd, VFS_passwd, VFS_session, VFS_sessionManager, VFS_acl, VFS_ephemeral, VFS_HD, VFS_QRC, VFS_cron, VFS_curl, VFS_iframe, VFS_pulse, VFS_stream, and VFS_tcp_server.
Definition at line 724 of file VFS_node.cpp.
|
virtualslot |
Once a VFS_request has been completed, a response will be issued back to its _origin.
t | The VFS_request object |
At this point, VFS_request::execute() will be called. If the VFS_request has a callback request, the payload is copied to the callback object, and issueResponse() is called for the callback request.
The VFS_request is then deleted using VFS_request::~VFS_request(), the destructor.
Definition at line 1870 of file VFS_node.cpp.
|
protectedvirtual |
Release a lock on this node.
r | The VFS_request object |
Subclasses of VFS_node can choose to implement locking however they see fit. This can be on the node level or on an individual field; it is up to the implementer to do these checks.
Definition at line 1081 of file VFS_node.cpp.
|
slot |
Remove a child node.
andDelete | Optionally delete the node |
This is a convenience slot. It will use the sender of the signal as the target node for removal.
The andDelete option will call node->deleteLater()
, which will happen when the event queue has emptied.
Definition at line 1629 of file VFS_node.cpp.
|
virtualslot |
Remove a child node from this node.
node | The node to remove, or null if a signal sender is to be used. |
rname | A string to write the deleted node's name back to. |
user | A user string to use for logging. |
Check to make sure the node is a child of this node. If it is, disconnect the finished() signal, and unmount() it. Note the change to this node by emitting a diff with a null value for the child name. This is really only meaningful for nodes with isContainer()==true
.
Although the node has been removed, it has not necessarily been deleted. It may be remounted elsewhere.
Definition at line 1660 of file VFS_node.cpp.
|
protectedvirtual |
Report debugging information about the current state of this node.
r | The VFS_request |
Used for debugging, return the subscription state and child list for this node. It will also provide a thread address and a few other things.
This can be viewed using the VFS_httpd_browser.
Definition at line 817 of file VFS_node.cpp.
|
virtual |
Additional details for a generated report.
This is useful in subclasses for providing class-specific information of any kind. For instance, VFS_cron::reportDetails() will list all active events.
Reimplemented in google_oauth2, VFS_mongo, VFS_pam, VFS_nopasswd, VFS_passwd, VFS_session, VFS_sessionManager, VFS_acl, VFS_datastore, VFS_ephemeral, VFS_HD, VFS_cron, VFS_curl, VFS_iframe, VFS_stream, VFS_tcp_client, VFS_tcp_server, VFS_tcp_export, VFS_udp_socket, VFS_remotoserver, and VFS_remotoserver_client.
Definition at line 900 of file VFS_node.cpp.
|
protectedvirtual |
Request a lock on this node.
r | The VFS_request object |
Subclasses of VFS_node can choose to implement locking however they see fit. This can be on the node level or on an individual field; it is up to the implementer to do these checks.
Definition at line 1065 of file VFS_node.cpp.
|
protectedvirtual |
Remove a child entry from a node, or the node itself.
r | The VFS_request |
A rm() operation will delete VFS_node entries. This is very nuanced. The intention is that find() will have navigated to a node, consuming path prefixes as it goes. When find is complete for a normal node, r->_path
will be an empty string. More complex nodes with virtual children will need to use r->_path
to determine an action.
By default, rm() will check for the non-existence of children, and an empty path. If those conditions are met, it will then emit finished(true), to signal the parent to remove() the child and call its destructor.
rm() should always set r->_success to a proper state.
Reimplemented in VFS_mongo, VFS_session, VFS_HD, VFS_QRC, and VFS_remotoserver_client.
Definition at line 1005 of file VFS_node.cpp.
|
protectedvirtual |
Submit a diff to a node.
r | The VFS_request object |
A submit() operation will apply a diff to the contents of a node. The base class implementation will report a warning, but _success will be true and a diff will be emitted.
Subclasses will want to apply the incoming diff, and if successful, emit a diff(). The emit is the notification mechanism for cascading changes to subscribers.
Reimplemented in VFS_mongo, VFS_acl, VFS_logger, VFS_ephemeral, VFS_HD, VFS_QRC, VFS_stream, and VFS_websocket_client.
Definition at line 978 of file VFS_node.cpp.
|
protectedvirtual |
Add an entry to this node's _subscription list.
r | The VFS_request object |
When a VFS node subscribes to a path on the VFS, subtreeRequest() will call find() to arrive at the node needed to create a subscription entry. An entry in the found node's VFS_node::_subscribers object is made which points back to the subscriber. The path fragment remaining after the find() is used as a key for the subscription entry.
An entry may already exist for that path and subscriber combination, in which case the subscription count is incremented here. The subscription count will decrement on unsubscribe(). If the subscription count becomes zero, the entry is removed.
This pattern would allow, for instance, 10 gui elements from one client to subscribe to a path, and as long as any one of them remains subscribed, the client would receive diffs.
When a subscription is requested, the node will execute a metadata() and read() call to populate the VFS_request object with initial data from the node. Otherwise, a client would need to immediately request a metadata() and read(), but because the system works asynchronously between threads, and the requests could be going over (a potentially slow) network, this would not work.
Care is taken that if a node exists in a VFS_node::_subscribers list, this node creates a connection to its unmounted() signal so that it can be removed, effectively unsubscribing it. The unmounted() signal is part of a VFS_node::~VFS_node()'s destructor sequence.
Please note that if a node intends to chain subscriptions together using a callback, the metadata() call will actually be a VFS_request::subscribe call. This is confusing at first, but is the desired functionality. To rephrase, if subscribing to a node causes that node to subscribe to another node, we want to satisfy the original request by populating the _data and _metadata fields of the request, while also creating subscription links between intermediate nodes. All of this comes for free, but is a little obfusticated in the simplicity of the call. The initial node being subscribed to will pass the request to subnodes by aborting the subscribe function when r->_success is not true or r->_callback exists.
The special metadata flag r->_metadata["__SUBSCRIBE_ONLY__"]=true
exists for the case when one wants to subscribe to a path, but doesn't care about receiving the node's data upon subscription.
Reimplemented in VFS_mongo, VFS_acl, VFS_HD, VFS_QRC, and VFS_cron.
Definition at line 1204 of file VFS_node.cpp.
|
virtualslot |
find() the target of a VFS_request, and execute the request
t | The VFS_request object |
If the result of find() is null, the request is marked _success=false
and issueResponse() is called. Otherwise the VFS_request is sent to the found node's executeRequest().
It's important to note that this is called in the thread that will actually be doing the execution.
Definition at line 1767 of file VFS_node.cpp.
QString VFS_node::uniqueChildName | ( | QString | name | ) |
Generate a unique child name.
name | The start name |
This will add a incremented number to the end of the provided name. Child names must be unique. }
Definition at line 2054 of file VFS_node.cpp.
|
virtual |
Unmount this node.
This will remove the signal/slot connection from this::diff to this::notifySubscribers().
When unmount() is called, the node will emit unmounted(), which can be a useful trigger for other operations.
A node may choose to subclass this, however the base implementation should always be called.
Reimplemented in VFS_thread.
Definition at line 1742 of file VFS_node.cpp.
|
protectedvirtual |
Remove an entry from this node's _subscription list.
r | The VFS_request object |
When a VFS_node unsubscribes from a path on the VFS, subtreeRequest() will call find() to arrive at the node the needs to remove the _subscription entry.
If _subscribers has an r->_path
entry, and within that an r->_originPath
entry, and within that an r->_origin
entry, then r->_metadata["unsubscriptions"]
or a default 1 will be used to know how far to decrement the subscription count.
As counts are decremented, fields are removed when empty. If all references to a subscriber node are removed from this subscription list, the unmounted() connection to it is removed from this node.
Reimplemented in VFS_acl, and VFS_cron.
Definition at line 1263 of file VFS_node.cpp.
|
virtualslot |
Remove all references to a subscriber from this node.
subscriber | The VFS_node to remove. |
This requires iterating over the whole _subscribers node, which may be expensive on a large set.
This function is called when a node is unmounted(), so that all subscription references are removed.
Definition at line 1336 of file VFS_node.cpp.
|
protectedvirtual |
Unsubscribe all references to a subpath.
path | The path to remove |
This method removes all references to a given path from the _subscribers list. This may be desired if files are removed from a VFS_HD node and therefore a path no longer exists.
For each node/path that was subscribed, emit a diff with null contents to notify subscribers of the removal.
Definition at line 1384 of file VFS_node.cpp.
|
virtual |
Check if a node name is valid.
name | The name to check |
A valid name will:
'/'
Definition at line 2101 of file VFS_node.cpp.
|
protectedvirtual |
Write data to this node.
r | The VFS_request object |
A write() operation replaces the data contents of a node. The base class implementation will do nothing and _success will be false.
For subclasses, this may be used to issue commands, replace entire files, or any other purpose. This is in contrast to submit(), which will attempt to apply a diff to data.
A write() operation should emit a diff() if it is successful. The emit is the notification mechanism for cascading changes to subscribers.
Reimplemented in VFS_mongo, VFS_sessionManager, VFS_ephemeral, VFS_HD, VFS_QRC, VFS_stream, VFS_tcp_client, VFS_udp_socket, VFS_remotoserver_client, and VFS_websocket_client.
Definition at line 767 of file VFS_node.cpp.
|
friend |
Definition at line 146 of file VFS_node.h.
|
friend |
Definition at line 147 of file VFS_node.h.
|
staticprivate |
The static global registry for all exiting nodes, used for thread safety checks.
Definition at line 215 of file VFS_node.h.
|
staticprivate |
The global registry mutex, which will lock when node creation or deletion is being performed.
Definition at line 216 of file VFS_node.h.
|
protected |
This node's children.
Definition at line 179 of file VFS_node.h.
|
mutableprotected |
A recursive mutex that is local to this node.
Definition at line 178 of file VFS_node.h.
|
protected |
This node's subscribers. These subscribers will receive diff notifications.
Definition at line 180 of file VFS_node.h.