2015-12-30 10 views
5

के साथ बाढ़ नियंत्रण लागू करें मैं एक रेडिस आधारित कार्यान्वयन के साथ ड्रूपल 8 की बाढ़ नियंत्रण सेवा के एसक्यूएल कार्यान्वयन को प्रतिस्थापित करने की कोशिश कर रहा हूं।रेडिस

देखें https://github.com/drupal/drupal/blob/8.0.x/core/lib/Drupal/Core/Flood/DatabaseBackend.php

आवश्यकताओं इस तरह हैं:

  • एक कार्रवाई/घटना से प्रत्येक घटना (जैसे में प्रवेश करने का प्रयास) एक समय समाप्ति, पहचानकर्ता और टाइमस्टैम्प
  • मैं जरूरत के साथ लॉग ऑन है यह रोकने में सक्षम होने के लिए कि किसी निश्चित कार्रवाई को किसी दिए गए समय सीमा में एन बार से अधिक किया जा सकता है
  • मैं समय-समय पर समाप्त होने वाली घटनाओं को साफ़ करने में सक्षम होना चाहता हूं
  • 10 मिनट में 3 की दहलीज के मामले में, यदि उपयोगकर्ता एक बार कोशिश करता है, तो 5 मिनट के बाद दो बार, वह अवरुद्ध हो जाता है और 5 मिनट के बाद एक बार फिर कोशिश कर सकता है। नहीं 10. जबकि दूसरा ऐसा करने का एक वैध तरीका होगा, यह नहीं है कि एसक्यूएल कार्यान्वयन कैसे काम करता है या परीक्षण कैसे काम करते हैं।
  • आप एपीआई के आधार पर देखते हैं, मैं भी जब घटना को किस सीमा है दर्ज की पता नहीं है सकते हैं, मैं केवल एक ही घटना की समाप्ति पता है।

कैसे लागू करने पर मेरे विचार इस:

  • हैं, तो एन घटनाओं दिए गए समय के लिए बंद कर दिया जाना चाहिए के बाद, तो यह आसान के लिए घटना के लिए एक एकल कुंजी के साथ होगा: पहचानकर्ता कि वृद्धि की जाती है, एक बार अधिकतम पहुंचने के बाद, यह तब तक बंद हो जाता है जब तक कि यह फिर से समाप्त न हो जाए और प्रत्येक आईएनसीआर समाप्ति (या नहीं) भी अपडेट करेगी।
  • मुझे कई प्रविष्टियां मिलीं जो सूची प्रविष्टियों की समाप्ति के बारे में पूछती हैं, जो संभव नहीं है। क्रमबद्ध सेट का उपयोग करके वर्कअराउंड हैं और सीमा से हटाएं। अधिकांश एक वैश्विक सेट का उपयोग करने लगते हैं, लेकिन फिर मैं आसानी से अपने ईवेंट + पहचानकर्ता को गिनती नहीं कर सकता - मुझे लगता है।

यह सब लिखने के बाद, मुझे वास्तव में यह पता चल सकता है कि यह कैसे काम कर सकता है, इसलिए मुझे लगता है कि मैं जो खोज रहा हूं वह इस बात पर प्रतिक्रिया है कि क्या यह समझ में आता है या कोई आसान तरीका है।

प्रत्येक घटना: पहचानकर्ता संयोजन एक कुंजी है और एक क्रमबद्ध सेट होता है। यह समाप्ति को स्कोर के रूप में उपयोग करता है और एक अद्वितीय मूल्य के रूप में, संभवतः माइक्रोसेकंड में निर्माण समय का उपयोग करता है। मैं यह पता लगाने के लिए गैर-कालबाह्य रिकॉर्ड गिनता हूं कि सीमा पार हो गई थी या नहीं। मैं प्रत्येक घटना की समाप्ति अद्यतन कर रहा हूं: प्रदान की गई समाप्ति विंडो के लिए पहचानकर्ता, इसलिए इसे तब तक स्वतः हटाया जाएगा जब तक कि कोई निर्दिष्ट पहचानकर्ता/ग्राहक हार नहीं मानता और कभी भी समाप्ति तक पहुंचने के बिना प्रयास करता रहता है। क्या सेट के अंदर रिकॉर्ड्स को साफ करना उचित है एक नया रजिस्टर करते समय? ऐसा लगता है कि यह काफी तेज़ है, और मैं कभी-कभी इसे कभी भी कर सकता हूं।

+0

वैसे, मैंने यहां पहला संस्करण लागू किया है: https://github.com/md-systems/redis/blob/8.x-1.x/src/Flood/PhpRedis.php। अभी भी कुछ प्रतिक्रिया की उम्मीद है कि यह एक अच्छा दृष्टिकोण है या नहीं। – Berdir

+0

ऐसा लगता है कि यह एक कोड समीक्षा प्रश्न है। मुझे लगता है कि आपको इसे यहां ले जाना चाहिए: http://codereview.stackexchange.com/ – t1gor

+0

अच्छा बिंदु, जब मैंने इसे बनाया तब तक कोई कोड नहीं था। मैं उस अवधारणा पर प्रतिक्रिया की तलाश कर रहा हूं जिसे मैंने लागू किया है और विशिष्ट कोड के बारे में कम है। लेकिन अगर इसे अधिक जवाब मिलेगा तो इसका जवाब देने में खुशी होगी। – Berdir

उत्तर

1

मैं बजाय एक reimplementing की, Redis 'कुंजी समाप्ति सुविधा का उपयोग करना पसंद करेंगे।

एक आसान विकल्प के बाद एक होगा:

  • सिर्फ एक सरल मूल्य है, जो प्रयासों की संख्या है सेट; "घटना प्रकार":: एक कुंजी "पहचानकर्ता" की तरह एक पैटर्न पर बनाया का उपयोग SETNX <identifier>:<event type> 1
  • अगर प्रतिक्रिया 1 है, यह, पहला प्रयास है, इसलिए आप इस कुंजी पर एक समयबाह्य सेट करें: EXPIRE <identifier>:<event type> <timeout in seconds>

  • अन्यथा आप INCR <identifier>:<event type> प्रयासों की संख्या में वृद्धि करते हैं आईएनसीआर की प्रतिक्रिया आपको विंडो के दौरान प्रयासों की संख्या प्रदान करेगी, इसलिए आप जानते हैं कि आप कार्रवाई की अनुमति दे सकते हैं या नहीं।

अगर आपको दिए गए समय विंडो में अनुमत प्रयासों की अधिकतम संख्या की तरह, और अधिक डाटा स्टोर करने की जरूरत है एक सरल मान के बजाय एक हैश इस्तेमाल कर सकते हैं,। इस मामले में आप शायद एचएसईटीएनएक्स और एचआईएनसीआर का उपयोग करेंगे।

+0

उत्तर के लिए धन्यवाद। मूल रूप से यह पहला बुलेट बिंदु है "इस पर लागू करने के तरीके पर मेरे विचार"। जैसा कि चौथी आवश्यकता में लिखा गया है, इससे थोड़ा अलग व्यवहार होता है। सीमा तक पहुंचने के बाद, यह दिए गए समय सीमा के लिए बंद कर देगा। हालांकि, मैं जिस इंटरफ़ेस को कार्यान्वित कर रहा हूं उसकी अपेक्षा यह है कि यह केवल तब तक लॉक होगा जब तक कि मैं दिए गए समय सीमा में सीमा से नीचे नहीं हूं, अब से पीछे की तरफ। – Berdir

+0

शायद मैं आपके बिंदु को समझ नहीं पा रहा हूं, लेकिन मुझे ऐसा नहीं लगता है। –

+0

आह, आप शुरुआत में, हर समय समाप्ति निर्धारित नहीं करते हैं। सच। लेकिन इसके विपरीत इसका असर होगा। समाप्ति के बाद, मैं फिर से पूर्ण दहलीज का उपयोग कर सकता था। तो यदि दहलीज 5 है और समाप्ति 5 मिनट है और मैं हर 1 मिनट में एक्स कर रहा हूं, तो आपके कार्यान्वयन में मैं इसे पहले मामले से 5 मिनट के तुरंत बाद 5 बार कर सकता हूं, जबकि मेरे मामले में, मैं केवल एक बार ऐसा कर सकता हूं , तो मैंने थ्रेसहोल्ड फिर से मारा है। – Berdir