0

I want to add a slight extension to a class in a ruby gem.

The gem I am using is private_pub : https://github.com/ryanb/private_pub and the class I am overriding is : https://github.com/ryanb/private_pub/blob/master/lib/private_pub/faye_extension.rb

I am have placed my implementation in a new file in config/initializers called faye_extension.rb. The piece I have added to the code is @@clients and the get_list_of_subscribers class method. The code in faye_extension.rb is as follows:

PrivatePub::FayeExtension
module PrivatePub
  # This class is an extension for the Faye::RackAdapter.
  # It is used inside of PrivatePub.faye_app.
  class FayeExtension
    # Callback to handle incoming Faye messages. This authenticates both
    # subscribe and publish calls.

#####  MY NEW BIT
    @@clients = 0
    def self.get_list_of_subscribers
      @@clients
    end

####


    def incoming(message, callback)
    @@clients = @@clients + 1
      if message["channel"] == "/meta/subscribe"
        authenticate_subscribe(message)
      elsif message["channel"] !~ %r{^/meta/}
        authenticate_publish(message)
      end
      callback.call(message)
    end

  private

    # Ensure the subscription signature is correct and that it has not expired.
    def authenticate_subscribe(message)
      subscription = PrivatePub.subscription(:channel => message["subscription"], :timestamp => message["ext"]["private_pub_timestamp"])
      if message["ext"]["private_pub_signature"] != subscription[:signature]
        message["error"] = "Incorrect signature."
      elsif PrivatePub.signature_expired? message["ext"]["private_pub_timestamp"].to_i
        message["error"] = "Signature has expired."
      end
    end

    # Ensures the secret token is correct before publishing.
    def authenticate_publish(message)
      if PrivatePub.config[:secret_token].nil?
        raise Error, "No secret_token config set, ensure private_pub.yml is loaded properly."
      elsif message["ext"]["private_pub_token"] != PrivatePub.config[:secret_token]
        message["error"] = "Incorrect token."
      else
        message["ext"]["private_pub_token"] = nil
      end
    end
  end
end

When deployed into my application, the incoming() method of the FayeExtension code is called multiple times, however if in a view somewhere I use the following line of code:

<h3><%= PrivatePub::FayeExtension.get_list_of_subscribers.to_s %></h3>

to call my get_list_of_subscribers class method, it always returns 0, despite me calling incoming() 5 times, where I would expect it to output 5. So it seems my @@clients = @@clients +1 code inside of incoming() is not referencing or updating correctly my global variable.

How can I alter the code to achieve this?

1 Answer 1

2

@@clients might be a class variable, but it is not shared between different processes. Applications deployed to production usually run multiple processes.

You will need to store that value somewhere where each process has access to: Your database, redis, memcache...

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.