Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Ruby

सॉलिड केबल के साथ रेल्स एक्शन केबल मास्टर करें: रेडिस के बिना रियल-टाइम ऐप्स बनाएं

रियल-टाइम फीचर्स वेब एप्लिकेशन में तेजी से महत्वपूर्ण होते जा रहे हैं, लेकिन हर रेल्स डेवलपर एक्शन केबल से परिचित नहीं है, जो फ्रेमवर्क की बिल्ट-इन वेबसॉकेट लाइब्रेरी है।

रेल्स एक्शन केबल क्यों उपयोग करें?

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

एक्शन केबल और वेबसॉकेट्स के साथ, आपका रेल्स ऐप लाइव इंटरैक्टिव फीचर्स प्रदान कर सकता है जिन्हें पारंपरिक रूप से सर्वर-रेंडर्ड ऐप में लागू करना कठिन था। रोजमर्रा के कुछ उपयोग के मामले हैं:

  • लाइव चैट एप्लिकेशन
  • नोटिफिकेशन और फीड्स
  • लाइव अपडेट के साथ कोलैबोरेटिव ऐप्स
  • लाइव स्पोर्ट्स या स्टॉक टिकर्स

संक्षेप में, एक्शन केबल पारंपरिक रिक्वेस्ट-रिस्पॉन्स साइकिल और रियल-टाइम इवेंट-ड्रिवन अपडेट के बीच की खाई को पाटता है। क्लाइंट साइड पर, रेल्स चैनल्स को सब्सक्राइब करने और ब्रॉडकास्ट प्राप्त करने के लिए एक जावास्क्रिप्ट कंज्यूमर प्रदान करता है। डेवलपर के रूप में, आप बैकएंड चैनल्स को परिभाषित करके एक्शन केबल के साथ इंटरैक्ट करते हैं (कंट्रोलर्स के समान, लेकिन रियल-टाइम स्ट्रीम्स के लिए) जिन्हें फ्रंट-एंड क्लाइंट्स सब्सक्राइब कर सकते हैं।

सॉलिड केबल क्या है?

यदि आपने पहले के रेल्स वर्जन में एक्शन केबल का उपयोग किया है, तो आप जानते होंगे कि प्रोडक्शन में यह आमतौर पर रेडिस (या PostgreSQL के NOTIFY) पर निर्भर करता है ताकि विभिन्न सर्वर प्रोसेसेज में मैसेजेस ब्रॉडकास्ट किए जा सकें। पब/सब सर्विस (अक्सर रेडिस) यह सुनिश्चित करती है कि एक रेल्स प्रोसेस से मैसेज अन्य सभी प्रोसेसेज तक पहुंचे ताकि वे इसे अपने कनेक्टेड वेबसॉकेट क्लाइंट्स को फॉरवर्ड कर सकें। इस अतिरिक्त इंफ्रास्ट्रक्चर की ऐतिहासिक रूप से एक्शन केबल का उपयोग करने के लिए आवश्यकता रही है।

रेल्स 8 में पेश किया गया सॉलिड केबल, आपके मौजूदा डेटाबेस को बैकएंड के रूप में उपयोग करके रेडिस जैसी बाहरी पब/सब सर्विस की आवश्यकता को प्रतिस्थापित करता है। सॉलिड केबल एक्शन केबल के लिए एक डेटाबेस-बैक्ड एडाप्टर है, ठीक वैसे ही जैसे सॉलिड क्यू एक्टिव जॉब के लिए और सॉलिड कैश एक्टिव कैश के लिए है। प्रत्येक इनकमिंग वेबसॉकेट मैसेज एक डेटाबेस टेबल में लिखा जाता है, और सभी एक्शन केबल इंस्टेंसेस नए मैसेजेस के लिए उस टेबल को पोल करते हैं ताकि उन्हें क्लाइंट्स को ब्रॉडकास्ट किया जा सके। यह बहुत तेजी से होता है (डिफ़ॉल्ट रूप से हर 100 मिलीसेकंड), जिससे निकट रियल-टाइम परफॉरमेंस मिलती है। मैसेजेस केवल थोड़े समय (डिफ़ॉल्ट रूप से 24 घंटे) के लिए स्टोर किए जाते हैं फिर प्रून किए जाते हैं, इसलिए आप हालिया मुद्दों को डीबग कर सकते हैं बिना डेटाबेस स्पेस की चिंता किए।

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

सॉलिड केबल के साथ रेल्स 8 ऐप बनाना

आप शायद सॉलिड केबल के साथ हैंड्स-ऑन होने के लिए उत्सुक हैं, तो आइए इसे रेल्स 8 एप्लिकेशन में जोड़ने और एक मिनिमल चैट रूम बनाने की प्रक्रिया से गुजरते हैं जहां कई यूजर्स रियल-टाइम में मैसेजेस एक्सचेंज कर सकते हैं।

एक उदाहरण ऐप बनाना

आप सॉलिड केबल को बैकएंड के रूप में उपयोग करते हुए एक्शन केबल के फंडामेंटल्स (चैनल्स, सब्सक्रिप्शन, ब्रॉडकास्टिंग) सीखेंगे। हम इस उदाहरण के लिए रेल्स 8 का उपयोग करेंगे, तो आगे बढ़ें और एक नया रेल्स ऐप बनाएं:

rails _8.1.0_ new solid_cable_chat --database=sqlite3

फिर, नए solid_cable_chat डायरेक्टरी में cd करें।

चूंकि आपने रेल्स 8 का उपयोग किया है, आपको रोल आउट करने के लिए सॉलिड केबल या किसी अन्य जेम को जोड़ने की आवश्यकता नहीं होगी। अधिकांश या सभी कॉन्फिगरेशन आपके लिए पहले से ही मौजूद होंगे। मैं आपको उन सभी के बारे में बताऊंगा ताकि आप रेल्स के पुराने वर्जन से आने पर भी समझ सकें।

सॉलिड केबल कॉन्फिगर करना

हम सॉलिड केबल सेटअप चलाकर शुरू करेंगे:

bin/rails solid_cable:install

यह जेनरेटर दो मुख्य काम करता है। यह एक config/cable.yml कॉन्फिगरेशन फाइल बनाता है जो सॉलिड केबल को केबल एडाप्टर के रूप में सेट करता है। यह एक db/cable_schema.rb फाइल भी बनाता है, जिसमें सॉलिड केबल के मैसेज टेबल के लिए डेटाबेस स्कीमा परिभाषा होती है। रेल्स के हालिया वर्जन rails new चलाने पर इन फाइलों को स्वचालित रूप से बनाते हैं।

अब, हमें सॉलिड केबल के लिए डेटाबेस सेटिंग्स कॉन्फिगर करने की आवश्यकता है। डिफ़ॉल्ट रूप से, रेल्स सॉलिड केबल के लिए एक अलग डेटाबेस का उपयोग करता है ताकि रियल-टाइम मैसेजिंग डेटा को आपके बाकी डेटा से अलग किया जा सके। डेवलपमेंट में, आप या तो उसी डेटाबेस का उपयोग कर सकते हैं या एक अलग सेट अप कर सकते हैं। मैं आपको दिखाऊंगा कि डेवलपमेंट में सॉलिड केबल के लिए एक अलग SQLite डेटाबेस का उपयोग कैसे करें। इसका मतलब एक नया "केबल" डेटाबेस कनेक्शन जोड़ना है।

सॉलिड केबल के लिए अपना डेटाबेस सेट करना

config/database.yml फाइल खोलें। डेवलपमेंट सेक्शन में, एक cable डेटाबेस जोड़ें। उदाहरण के लिए, यदि आप SQLite का उपयोग कर रहे हैं (रेल्स का डेवलपमेंट के लिए डिफ़ॉल्ट):

development:
  primary: <<: *default
    database: storage/development.sqlite3
  cable: <<: *default
    database: storage/development_cable.sqlite3
    migrations_paths: db/cable_migrate

production:
  primary: <<: *default
    database: storage/production.sqlite3
  cache: <<: *default
    database: storage/production_cache.sqlite3
    migrations_paths: db/cache_migrate
  queue: <<: *default
    database: storage/production_queue.sqlite3
    migrations_paths: db/queue_migrate
  cable: <<: *default
    database: storage/production_cable.sqlite3
    migrations_paths: db/cable_migrate

फिर से, यदि आप रेल्स के हालिया वर्जन पर हैं, तो यह कॉन्फिगरेशन पहले से ही मौजूद होगा।

अब config/cable.yml खोलें। सॉलिड केबल को प्रोडक्शन में डिफ़ॉल्ट एडाप्टर होना चाहिए। हम डेवलपमेंट में भी सॉलिड केबल को सक्षम करना चाहते हैं (ताकि हम लोकलहोस्ट पर अपने चैट का परीक्षण कर सकें)। cable.yml को संपादित करें ताकि डेवलपमेंट में solid_cable एडाप्टर का उपयोग हो और यह हमारे द्वारा कॉन्फिगर किए गए cable डेटाबेस को इंगित करे:

development:
  adapter: solid_cable
  connects_to:
    database:
      writing: cable
  polling_interval: 0.1.seconds
  message_retention: 1.day

test:
  adapter: test

production:
  adapter: solid_cable
  connects_to:
    database:
      writing: cable
  polling_interval: 0.1.seconds
  message_retention: 1.day

उपरोक्त cable.yml में, हमने डेवलपमेंट एडाप्टर को solid_cable पर सेट किया और प्रोडक्शन सेटिंग से सेटिंग्स कॉपी कीं। connects_to सेटिंग एक्शन केबल को मैसेजेस स्टोर करने के लिए केबल डेटाबेस का उपयोग करने के लिए कहती है (जैसा कि database.yml में परिभाषित है)। आपको यह परिवर्तन रेल्स के हालिया वर्जन पर भी करना होगा।

छोटे ऐप्स के लिए, आप सॉलिड केबल की टेबल को रखने के लिए उसी प्राइमरी डेटाबेस का उपयोग कर सकते हैं (स्कीमा को माइग्रेशन में कॉपी करके और अलग DB कॉन्फिग को हटाकर)। लेकिन संभावित परफॉरमेंस इंटरफेरेंस से बचने के लिए अलग डेटाबेस का उपयोग करने की सिफारिश की जाती है।

अंत में, यह सुनिश्चित करने के लिए rails db:prepare चलाएं कि डेटाबेस तैयार है। प्रोडक्शन में भी आपको यह करना होगा यदि आप अपना ऐप शिप कर रहे हैं।

एक्शन केबल चैनल सेट करना

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

rails generate channel UserChat

जनरेटेड app/channels/user_chat_channel.rb खोलें, और इसे नई लॉजिक के साथ अपडेट करें।

जब कोई क्लाइंट UserChatChannel को सब्सक्राइब करता है (चैट पेज खोलकर), subscribed कॉलबैक आह्वान किया जाता है। हम इस कॉलबैक में stream_from "user_chat_channel" कॉल करना चाहते हैं ताकि "user_chat_channel" नामक ब्रॉडकास्ट से स्ट्रीमिंग शुरू हो सके।

अनिवार्य रूप से, हम कह रहे हैं "किसी भी डेटा को सुनें जो user_chat_channel स्ट्रीम पर ब्रॉडकास्ट किया गया है और इसे इस चैनल के क्लाइंट्स को पास करें।" इस चैनल को सब्सक्राइब करने वाले सभी यूजर्स "user_chat_channel" पर मैसेज ब्रॉडकास्ट प्राप्त करेंगे।

हम एक कस्टम एक्शन भी परिभाषित करना चाहते हैं, जिसे हम talk(data) कहेंगे। एक चैनल में कोई भी पब्लिक मेथड क्लाइंट साइड से आह्वान किया जा सकता है। इस मामले में, जब क्लाइंट perform("talk", { content: "Hello World" }) कॉल करता है, तो सर्वर पर talk मेथड निष्पादित होता है।

हमारे talk का कार्यान्वयन क्लाइंट द्वारा भेजी गई मैसेज सामग्री लेता है और इसे ActionCable.server.broadcast का उपयोग करके "user_chat_channel" को सब्सक्राइब करने वाले सभी को भेजता है। इसका मतलब है कि हर सब्सक्राइबर (सेंडर सहित) रियल-टाइम में मैसेज डेटा प्राप्त करेगा। हम केवल मैसेज टेक्स्ट वाला हैश ब्रॉडकास्ट करते हैं; आप आवश्यकतानुसार अन्य जानकारी (जैसे यूजरनेम या टाइमस्टैम्प) शामिल कर सकते हैं। नोट: एक वास्तविक ऐप में, आप यहां मैसेज को डेटाबेस में भी पर्सिस्ट कर सकते हैं या वैलिडेशन कर सकते हैं। सरलता के लिए, हम इसे केवल ब्रॉडकास्ट कर रहे हैं।

class UserChatChannel < ApplicationCable::Channel
  def subscribed
    stream_from "user_chat_channel"
  end

  def unsubscribed
    # चैनल से अनसब्सक्राइब करते समय आवश्यक कोई क्लीनअप
  end

  def talk(data)
    message = data["content"]
    ActionCable.server.broadcast("user_chat_channel", { content: message })
  end
end

क्लाइंट में हमारे चैनल का कंज्यूमर बनाना

अब जब हमने बैकएंड बना लिया है, तो हमें फ्रंट-एंड को हुक अप करने की आवश्यकता है ताकि यूजर्स वेबसॉकेट के माध्यम से मैसेज भेज और प्राप्त कर सकें ताकि रियल-टाइम कार्यक्षमता का प्रदर्शन हो सके।

रेल्स 8 एक्शन केबल के जावास्क्रिप्ट सामान के साथ बेक्ड-इन आता है। जेनरेटर ने हमारे लिए app/javascript/channels/user_chat_channel.js फाइल बनाई। हम वहां क्लाइंट व्यवहार को लागू करेंगे।

app/javascript/channels/user_chat_channel.js खोलें और इसे अपडेट करें:

import consumer from "channels/consumer";
const userChatChannel = consumer.subscriptions.create("UserChatChannel", {
  connected() {
    console.log("Connected to UserChatChannel.");
  },
  disconnected() {
    console.log("Disconnected from UserChatChannel.");
  },
  received(data) {
    const messagesDiv = document.getElementById("messages");
    if (messagesDiv && data.content) {
      const messageElement = document.createElement("p");
      messageElement.textContent = data.content;
      messagesDiv.appendChild(messageElement);
    }
  }
});

function sendMessage(content) {
  userChatChannel.perform("talk", { content: content });
}
export { sendMessage };
window.sendMessage = sendMessage;

यहां हम consumer.subscriptions.create("UserChatChannel", {...}) का उपयोग करके सर्वर पर हमारे UserChatChannel की सदस्यता बनाते हैं। यह एक सब्सक्रिप्शन ऑब्जेक्ट लौटाता है जिसका उपयोग हम चैनल के साथ इंटरैक्ट करने के लिए कर सकते हैं।

connected() कॉलबैक तब चलेगा जब कनेक्शन स्थापित हो जाएगा। यहां हम केवल कंसोल पर लॉग करते हैं ताकि हम देख सकें कि यह काम करता है।

disconnected() कॉलबैक तब चलता है जब वेबसॉकेट डिस्कनेक्ट होता है।

received(data) कॉलबैक महत्वपूर्ण है! यह कॉलबैक तब फायर होता है जब हमारा चैनल सर्वर से ब्रॉडकास्ट प्राप्त करता है। UserChatChannel#talk में हमने { content: message } ब्रॉडकास्ट किया। यहां data आर्गुमेंट वही हैश होगा। यह हमारे चैट लॉग को तुरंत सभी कनेक्टेड क्लाइंट्स के लिए अपडेट करेगा जब एक नया मैसेज आएगा।

हम एक हेल्पर sendMessage(content) भी परिभाषित करते हैं जो userChatChannel.perform("talk", { content: ... }) कॉल करता है। यह सर्वर-साइड talk एक्शन को रिक्वेस्ट भेजता है जिसे हमने परिभाषित किया था, जिसमें यूजर द्वारा टाइप की गई मैसेज सामग्री शामिल होती है।

अब हमें यूजर्स के लिए मैसेज भेजने और प्राप्त करने के लिए एक सिंपल UI की आवश्यकता है। आइए इसके लिए एक बहुत ही बेसिक व्यू बनाएं।

हमारे उदाहरण ऐप के लिए एक सिंपल UI बनाना

पहले, एक कंट्रोलर जेनरेट करें:

rails generate controller UserChat index

अब, इंडेक्स व्यू खोलें और इसे कुछ बेसिक सेटअप दें:

<h1>Chats from Users</h1>
<div id="messages" style="border: 1px solid #ccc; padding: 1em; height: 200px; overflow-y: auto; margin-bottom: 1em;">
  <!-- Messages will appear here -->
</div>
<form id="chat-form" onsubmit="event.preventDefault(); sendMessage(document.getElementById('chat-input').value); document.getElementById('chat-input').value = '';">
  <input type="text" id="chat-input" placeholder="Type a message..." autocomplete="off" style="width: 80%;" />
  <button type="submit">Send</button>
</form>

अंत में, config/routes.rb में रूट रूट को इस नए रूट पर इंगित करने के लिए सेट करें:

root "user_chat#index"

यह सब कैसे एक साथ काम करता है दिखाना

हमारा सिंपल चैट ऐप टेस्टिंग के लिए तैयार है! bin/dev के साथ प्रोजेक्ट चलाएं और localhost:3000 पर जाएं:

सॉलिड केबल के साथ रेल्स एक्शन केबल मास्टर करें: रेडिस के बिना रियल-टाइम ऐप्स बनाएं

रियल-टाइम अपडेट दिखाने के लिए, ऐप को दो अलग-अलग ब्राउज़र टैब में खोलें। एक टैब में, "Hello from tab number 1!" जैसा मैसेज दर्ज करें।

सॉलिड केबल के साथ रेल्स एक्शन केबल मास्टर करें: रेडिस के बिना रियल-टाइम ऐप्स बनाएं यदि आप दूसरे टैब से मैसेज भेजते हैं, तो आप इसे पहले टैब में देखेंगे!

सॉलिड केबल के साथ रेल्स एक्शन केबल मास्टर करें: रेडिस के बिना रियल-टाइम ऐप्स बनाएं

रेल्स एक्शन केबल को प्रोडक्शन में डेप्लॉय करना

सॉलिड केबल वेबसॉकेट मैसेजेस को डेटाबेस टेबल में स्टोर करता है, और हमारे उदाहरण ऊपर ने डिफ़ॉल्ट cable डेटाबेस का उपयोग किया। रेल्स 8 नए ऐप्स में सॉलिड केबल के लिए SQLite को डिफ़ॉल्ट करता है, लेकिन आप तकनीकी रूप से इसे config/database.yml में cable सेक्शन जोड़कर किसी भी रेल्स-सपोर्टेड डेटाबेस पर इंगित कर सकते हैं।

वास्तव में, प्रोडक्शन में सॉलिड केबल के लिए एक अलग डेटाबेस का उपयोग करना अनुशंसित है ताकि रियल-टाइम मैसेजिंग लोड को आपके बाकी डेटा से अलग किया जा सके। उदाहरण के लिए, आप सॉलिड केबल के लिए एक समर्पित app_production_cable डेटाबेस प्रोविजन कर सकते हैं जबकि आपका प्राइमरी ऐप डेटा app_production में रहता है।

यह पृथक्करण चैट या नोटिफिकेशन ट्रैफिक को आपके मुख्य एप्लिकेशन क्वेरीज के साथ प्रतिस्पर्धा करने से रोकता है। उस ने कहा, छोटे ऐप्स के लिए, ऐप डेटा और केबल मैसेजेस दोनों के लिए एक ही डेटाबेस का उपयोग करना आमतौर पर ठीक है।

गैर-स्पष्ट हिस्सा यह सुनिश्चित करना है कि सॉलिड केबल डेटाबेस आपके डेप्लॉयमेंट सेटअप में शामिल है। यदि आप एक अलग डेटाबेस का उपयोग करते हैं, तो याद रखें कि rails db:prepare या rails db:migrate चलाएं ताकि रेल्स प्रोडक्शन में messages टेबल बनाए।

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

पोलिंग इंटरवल कॉन्फिगर करना

सॉलिड केबल के लिए पोलिंग फ्रीक्वेंसी कॉन्फिगरेबल है, जिससे आप लेटेंसी को डेटाबेस लोड के साथ संतुलित कर सकते हैं। इंटरवल को कम करने से अधिक बार पोलिंग होती है, जो नए मैसेजेस को लेने का समय कम करती है, लेकिन आपके डेटाबेस पर अधिक SELECT क्वेरीज की कीमत पर।

इसके विपरीत, एक लंबा इंटरवल डेटाबेस उपयोग को हल्का करेगा लेकिन ब्रॉडकास्ट और अपडेट में अधिक देरी लाएगा। व्यवहार में, डिफ़ॉल्ट 0.1s (प्रति सेकंड 10 पोल) एक अच्छा प्रारंभिक बिंदु है जो अधिकांश डेटाबेस को अभिभूत किए बिना प्रतीत होता है रियल-टाइम अपडेट प्रदान करता है।

सॉलिड केबल सॉलिड ट्रिफेक्टा का एक आवश्यक स्तंभ है

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

"सॉलिड ट्रिफेक्टा" का उपयोग आपको इंटरैक्टिव एप्लिकेशन बनाने के लिए न्यूनतम इंफ्रास्ट्रक्चर ओवरहेड के साथ एक उल्लेखनीय रूप से कार्यात्मक फ्रेमवर्क देता है।

सॉलिड केबल और इसके सहोदरों का मुख्य लाभ सरलता है। हमारे रेल्स ऐप की रियल-टाइम कार्यक्षमता पर्दे के पीछे केवल ऐप के डेटाबेस के साथ आउट-ऑफ-द-बॉक्स काम करती है। डेप्लॉयमेंट सरल है (कोई रेडिस या अतिरिक्त सेवाएं नहीं), और कई एप्लिकेशन के लिए, परफॉरमेंस पर्याप्त से अधिक है।

बेशक, किसी भी रेल्स एप्लिकेशन को प्रोडक्शन में चलाते समय, आपको उन मुद्दों के लिए इसकी निगरानी करनी चाहिए जो आपके यूजर्स का सामना कर सकते हैं। क्या आप जानना चाहेंगे कि आपके एक्शन केबल कंज्यूमर्स और चैनल्स के साथ कुछ गलत होने पर आपके यूजर्स से पहले?

हनीबैजर रेल्स एरर और परफॉरमेंस मॉनिटरिंग के लिए एक उत्कृष्ट विकल्प है, जो रियल-टाइम एप्लिकेशन डेप्लॉय करने के लिए महत्वपूर्ण हैं। हनीबैजर आपको तुरंत अलर्ट करता है जब आपके एप्लिकेशन में कहीं भी एरर होते हैं - बैकएंड में और क्लाइंट साइड पर - और रैपिड सर्च, ट्रबलशूटिंग और रिजॉल्यूशन के लिए आपके एप्लिकेशन लॉग्स और परफॉरमेंस डेटा को खींचता है।

शुरू करने के लिए हनीबैजर के लिए साइन अप करें!

  1. HTML स्पेस टैग जोड़ना HTML स्पेस टैग जोड़ना

    HTML लिखते समय, आप देखेंगे कि स्पेसबार दबाने पर बने अतिरिक्त स्पेस ब्राउज़र में टेक्स्ट रेंडर होने पर दिखाई नहीं देते। उदाहरण के लिए: <p>April is the cruelest month,</p> <p>April is the cruelest month,</p> पहले <p> टैग में, प्रत्येक शब्द के बीच केवल एक स्पेस है। लेकिन

  1. C++ में रूट-टू-लीफ पथों पर लंबाई   K वाले नोड्स को हटाना C++ में रूट-टू-लीफ पथों पर लंबाई < K वाले नोड्स को हटाना

    एक ट्री दिया गया है, और हमें दिए गए k से कम लंबाई वाले पथ के लीफ नोड को हटाने की आवश्यकता है, उदाहरण के लिए। इनपुट - K = 4. आउटपुट - व्याख्या I लंबाई = 3 अब जैसा कि आप देख सकते हैं पथ 3, 4, 5 की लंबाई 3 है जो दिए गए k से कम है इसलिए हम इन पथों के लीफ नोड्स को हटा देते हैं यानी D, H, I। अब पथ 4

  1. डॉकराइज्ड टाइम-सीरीज़ मॉडल में स्टेट को बनाए रखकर निरंतर पूर्वानुमान सटीकता सुनिश्चित करना: Redis के साथ डॉकराइज्ड टाइम-सीरीज़ मॉडल में स्टेट को बनाए रखकर निरंतर पूर्वानुमान सटीकता सुनिश्चित करना: Redis के साथ

    क्या आपने कभी एक शानदार टाइम-सीरीज़ मॉडल बनाया है, जो बिक्री का पूर्वानुमान लगा सकता है या स्टॉक की कीमतों की भविष्यवाणी कर सकता है, केवल यह देखने के लिए कि यह वास्तविक दुनिया में विफल हो जाता है? खैर, यह एक आम निराशा है। आपका मॉडल आपकी मशीन पर पूरी तरह से काम करता है, लेकिन जिस क्षण आप इसे डॉकर कं