diff options
-rw-r--r-- | common/facade.cpp | 57 | ||||
-rw-r--r-- | common/resourceaccess.cpp | 45 | ||||
-rw-r--r-- | common/resourceaccess.h | 16 |
3 files changed, 61 insertions, 57 deletions
diff --git a/common/facade.cpp b/common/facade.cpp index 1b91ce4..1219887 100644 --- a/common/facade.cpp +++ b/common/facade.cpp | |||
@@ -32,63 +32,6 @@ using namespace Sink; | |||
32 | #undef DEBUG_AREA | 32 | #undef DEBUG_AREA |
33 | #define DEBUG_AREA "client.facade" | 33 | #define DEBUG_AREA "client.facade" |
34 | 34 | ||
35 | /** | ||
36 | * A factory for resource access instances that caches the instance for some time. | ||
37 | * | ||
38 | * This avoids constantly recreating connections, and should allow a single process to have one connection per resource. | ||
39 | */ | ||
40 | class ResourceAccessFactory { | ||
41 | public: | ||
42 | static ResourceAccessFactory &instance() | ||
43 | { | ||
44 | static ResourceAccessFactory *instance = 0; | ||
45 | if (!instance) { | ||
46 | instance = new ResourceAccessFactory; | ||
47 | } | ||
48 | return *instance; | ||
49 | } | ||
50 | |||
51 | Sink::ResourceAccess::Ptr getAccess(const QByteArray &instanceIdentifier) | ||
52 | { | ||
53 | if (!mCache.contains(instanceIdentifier)) { | ||
54 | //Reuse the pointer if something else kept the resourceaccess alive | ||
55 | if (mWeakCache.contains(instanceIdentifier)) { | ||
56 | auto sharedPointer = mWeakCache.value(instanceIdentifier).toStrongRef(); | ||
57 | if (sharedPointer) { | ||
58 | mCache.insert(instanceIdentifier, sharedPointer); | ||
59 | } | ||
60 | } | ||
61 | if (!mCache.contains(instanceIdentifier)) { | ||
62 | //Create a new instance if necessary | ||
63 | auto sharedPointer = Sink::ResourceAccess::Ptr::create(instanceIdentifier); | ||
64 | QObject::connect(sharedPointer.data(), &Sink::ResourceAccess::ready, sharedPointer.data(), [this, instanceIdentifier](bool ready) { | ||
65 | if (!ready) { | ||
66 | mCache.remove(instanceIdentifier); | ||
67 | } | ||
68 | }); | ||
69 | mCache.insert(instanceIdentifier, sharedPointer); | ||
70 | mWeakCache.insert(instanceIdentifier, sharedPointer); | ||
71 | } | ||
72 | } | ||
73 | if (!mTimer.contains(instanceIdentifier)) { | ||
74 | auto timer = new QTimer; | ||
75 | //Drop connection after 3 seconds (which is a random value) | ||
76 | QObject::connect(timer, &QTimer::timeout, timer, [this, instanceIdentifier]() { | ||
77 | mCache.remove(instanceIdentifier); | ||
78 | }); | ||
79 | timer->setInterval(3000); | ||
80 | mTimer.insert(instanceIdentifier, timer); | ||
81 | } | ||
82 | auto timer = mTimer.value(instanceIdentifier); | ||
83 | timer->start(); | ||
84 | return mCache.value(instanceIdentifier); | ||
85 | } | ||
86 | |||
87 | QHash<QByteArray, QWeakPointer<Sink::ResourceAccess> > mWeakCache; | ||
88 | QHash<QByteArray, Sink::ResourceAccess::Ptr> mCache; | ||
89 | QHash<QByteArray, QTimer*> mTimer; | ||
90 | }; | ||
91 | |||
92 | template<class DomainType> | 35 | template<class DomainType> |
93 | GenericFacade<DomainType>::GenericFacade(const QByteArray &resourceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory , const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess) | 36 | GenericFacade<DomainType>::GenericFacade(const QByteArray &resourceIdentifier, const DomainTypeAdaptorFactoryInterface::Ptr &adaptorFactory , const QSharedPointer<Sink::ResourceAccessInterface> resourceAccess) |
94 | : Sink::StoreFacade<DomainType>(), | 37 | : Sink::StoreFacade<DomainType>(), |
diff --git a/common/resourceaccess.cpp b/common/resourceaccess.cpp index 80d60e8..555d807 100644 --- a/common/resourceaccess.cpp +++ b/common/resourceaccess.cpp | |||
@@ -594,6 +594,51 @@ bool ResourceAccess::processMessageBuffer() | |||
594 | return d->partialMessageBuffer.size() >= headerSize; | 594 | return d->partialMessageBuffer.size() >= headerSize; |
595 | } | 595 | } |
596 | 596 | ||
597 | ResourceAccessFactory &ResourceAccessFactory::instance() | ||
598 | { | ||
599 | static ResourceAccessFactory *instance = 0; | ||
600 | if (!instance) { | ||
601 | instance = new ResourceAccessFactory; | ||
602 | } | ||
603 | return *instance; | ||
604 | } | ||
605 | |||
606 | Sink::ResourceAccess::Ptr ResourceAccessFactory::getAccess(const QByteArray &instanceIdentifier) | ||
607 | { | ||
608 | if (!mCache.contains(instanceIdentifier)) { | ||
609 | //Reuse the pointer if something else kept the resourceaccess alive | ||
610 | if (mWeakCache.contains(instanceIdentifier)) { | ||
611 | auto sharedPointer = mWeakCache.value(instanceIdentifier).toStrongRef(); | ||
612 | if (sharedPointer) { | ||
613 | mCache.insert(instanceIdentifier, sharedPointer); | ||
614 | } | ||
615 | } | ||
616 | if (!mCache.contains(instanceIdentifier)) { | ||
617 | //Create a new instance if necessary | ||
618 | auto sharedPointer = Sink::ResourceAccess::Ptr::create(instanceIdentifier); | ||
619 | QObject::connect(sharedPointer.data(), &Sink::ResourceAccess::ready, sharedPointer.data(), [this, instanceIdentifier](bool ready) { | ||
620 | if (!ready) { | ||
621 | mCache.remove(instanceIdentifier); | ||
622 | } | ||
623 | }); | ||
624 | mCache.insert(instanceIdentifier, sharedPointer); | ||
625 | mWeakCache.insert(instanceIdentifier, sharedPointer); | ||
626 | } | ||
627 | } | ||
628 | if (!mTimer.contains(instanceIdentifier)) { | ||
629 | auto timer = new QTimer; | ||
630 | //Drop connection after 3 seconds (which is a random value) | ||
631 | QObject::connect(timer, &QTimer::timeout, timer, [this, instanceIdentifier]() { | ||
632 | mCache.remove(instanceIdentifier); | ||
633 | }); | ||
634 | timer->setInterval(3000); | ||
635 | mTimer.insert(instanceIdentifier, timer); | ||
636 | } | ||
637 | auto timer = mTimer.value(instanceIdentifier); | ||
638 | timer->start(); | ||
639 | return mCache.value(instanceIdentifier); | ||
640 | } | ||
641 | |||
597 | } | 642 | } |
598 | 643 | ||
599 | #pragma clang diagnostic push | 644 | #pragma clang diagnostic push |
diff --git a/common/resourceaccess.h b/common/resourceaccess.h index 4c10adb..3b03210 100644 --- a/common/resourceaccess.h +++ b/common/resourceaccess.h | |||
@@ -111,4 +111,20 @@ private: | |||
111 | Private * const d; | 111 | Private * const d; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | /** | ||
115 | * A factory for resource access instances that caches the instance for some time. | ||
116 | * | ||
117 | * This avoids constantly recreating connections, and should allow a single process to have one connection per resource. | ||
118 | */ | ||
119 | class ResourceAccessFactory { | ||
120 | public: | ||
121 | static ResourceAccessFactory &instance(); | ||
122 | Sink::ResourceAccess::Ptr getAccess(const QByteArray &instanceIdentifier); | ||
123 | |||
124 | QHash<QByteArray, QWeakPointer<Sink::ResourceAccess> > mWeakCache; | ||
125 | QHash<QByteArray, Sink::ResourceAccess::Ptr> mCache; | ||
126 | QHash<QByteArray, QTimer*> mTimer; | ||
127 | }; | ||
128 | |||
129 | |||
114 | } | 130 | } |