Redis vs Class variables in Rails - ruby-on-rails

Im using Sidekiq, Redis, Websocket-rails inside of Rails. With sidekiq having server-side Class. Now, when adding more functionality, i cant anymore use instance variables inside my Sidekiq Class's methods, i need to share information between methods. Sidekiq class also inherits from Websocket class, to be available websockets.
Right now, i have 2000/per second data change for objects. Using 95% instance variables, 5% pushing/getting from Redis, to make lower I/O.
Im considering, using class variables or making all 100% on Redis. Im not sure about or it wont overload my background jobs with that big data transfer count, which goes bigger with every new client. I'm using heroku free Dyno, dont want to buy better server yet. But using class variables would be less I/O, and probably unsafe, becouse it inherits from Websocket-rails? Im doing this project partly to show something to employers, that i can program, to get my 1-st IT job. I care how they react to those class variables. What employers would say about class variables? And which one to choose?

You can absolutely use instance variables in your Sidekiq worker. You cannot use class or class-instance variables.
class MyWorker
include Sidekiq::Worker
def perform(a, b)
#a = a # instance variable, no problem!
##a = a # class variable, big problem!
self.set_a(a)
end
def self.set_a(a)
#a = a # class instance variable, big problem!
end
end

Class variables have their places, if they represent a concept that is unchangeable and should live as a definition of something, like a configuration throughout the application, or some fundamental multiplier of a part of the application domain/business.
But, just because things are unchanging, that doesn't mean they have to be a class variable. You can have an instance of a class to be always setup with the same values, and then share the instance. Kind of like a singleton, but not necessarily being a singleton, just being a widely shared variable that is part of the input on the start of a given process.
So instead of using Sidekiq to store data for this unchanging thing, and rather than using class variables, you can achieve a cleaner design by doing something like
class ImportantThing
def initialize(name, other_property)
#name = name
#other_property = other_property
end
# Other methods you wish to define the behavior of the thing
end
then you can
the_important_thing = ImportantThing.new("foobar", 3.46)
do_important_process(the_important_thing)
then as far as the important process you are running is concerned, the important thing is anything that behaves like a important thing, and it doesn't matter if it is a globally setup or ever unchanging.
This makes for a easy to test architecture which is generally a sign of clear and decoupled design.

Related

Creating and storing generic methods in ruby on rails

I'm making a method inside a Ruby on Rails app called "print" that can take any string and converts it into a png. I've been told it's not good to make class methods for base ruby classes like String or Array or Hash, etc. so "some string to print".print is probably not something I should do.
I was thinking about making a subclass of String called Print (class Print < String) and storing it in my lib/assets folder. So it would look like: Print.new("some string to print"). So my question is, am I on the right track by 1) creating a sub-class from String and 2) storing it in lib/assets?
Any guidance would be greatly appreciated!
Answers to your question will necessarily be subjective because there are always be many answers to "where should I put functionality?", according to preference, principle, habit, customs, etc. I'll list a few and describe them, maybe add some of my personal opinions, but you'll ultimately have to choose and accept the consequences.
Note: I'll commonly refer to the common degenerate case of "losing namespacing scope" or "as bad as having global methods".
Monkeypatch/Extend String
Convenient and very "OO-message-passing" style at the cost of globally affecting all String in your application. That cost can be large because doing so breaks an implicit boundary between Ruby core and your application and it also scatters a component of "your application" in an external place. The functionality will have global scope and at worst will unintentionally interact with other things it shouldn't.
Worthy mention: Ruby has a Refinements feature that allows you to do do "scoped monkeypatching".
Worthy mention 2: Ruby also lets you includes modules into existing classes, like String.class_eval { include MyCustomization } which is slightly better because it's easier to tell a customization has been made and where it was introduced: "foo".method(:custom_method).owner will reveal it. Normal Monkeypatching will make it as if the method was defined on String itself.
Utils Module
Commonly done in all programming languages, a Util module is simply a single namespace where class methods/static methods are dumped. This is always an option to avoid the global pollution, but if Util ends up getting used everywhere anyways and it gets filled to the brim with unrelated methods, then the value of namespacing is lost. Having a method in a Util module tends to signify not enough thought was put into organizing code, since without maintenance, at it's worst, it's not much better than having global methods.
Private Method
Suppose you only need it in one class -- then it's easy to just put it into one private method. What if you need it in many classes? Should you make it a private method in a base class? If the functionality is inherent to the class, something associated with the class's identity, then Yes. Used correctly, the fact that this message exists is made invisible to components outside of that class.
However, this has the same downfall as the Rails Helper module when used incorrectly. If the next added feature requires that functionality, you'll be tempted to add the new feature to the class in order to have access to it. In this way the class's scope grows over time, eventually becoming near-global in your application.
Helper Module
Many Rails devs would suggest to put almost all of these utility methods inside rails Helper modules. Helper modules are kind of in between Utils Module and Private Method options. Helpers are included and have access to private members like Private Methods, and they suggest independence like Utils Modules (but do not guarantee it). Because of these properties, they tend to end up appearing everywhere, losing namespacing, and they end up accessing each other's private members, losing independence. This means it's more powerful, but can easily become much worse than either free-standing class/static methods or private methods.
Create a Class
If all the cases above degenerate into a "global scope", what if we forcibly create a new, smaller scope by way of a new class? The new class's purpose will be only to take data in and transform it on request on the way out. This is the common wisdom of "creating many, small classes", as small classes will have smaller scopes and will be easier to handle.
Unfortunately, taking this strategy too far will result in having too many tiny components, each of which do almost nothing useful by themselves. You avoid the ball of mud, but you end up with a chunky soup where every tiny thing is connected to every other tiny thing. It's just as complicated as having global methods all interconnected with each other, and you're not much better off.
Meta-Option: Refactor
Given the options above all have the same degenerate case, you may think there's no hope and everything will always eventually become horribly global -- Not True! It's important to understand they all degenerate in different ways.
Perhaps functionality 1, 2, 3, 4... 20 as Util methods are a complete mess, but they work cohesively as functionality A.1 ~ A.20 within the single class A. Perhaps class B is a complete mess and works better broken apart into one Util method and two private methods in class C.
Your lofty goal as an engineer will be to organize your application in a configuration that avoids all these degenerate cases for every bit of functionality in the system, making the system as a whole only as complex as necessary.
My advice
I don't have full context of your domain, and you probably won't be able to communicate that easily in a SO question anyways, so I can't be certain what'll work best for you.
However, I'll point out that it's generally easier to combine things than it is to break them apart. I generally advise starting with class/static methods. Put it in Util and move it to a better namespace later (Printer?). Perhaps in the future you'll discover many of these individual methods frequently operate on the same inputs, passing the same data back and forth between them -- this may be a good candidate for a class. This is often easier than starting off with a class or inheriting other class and trying to break functionality apart, later.

Does resque share class variables?

class ViewJob
##counter = 0
def initialize
...
end
end
Do all Resque job instances of this class share the same ##counter? Or is there any other way to share variables in Resque jobs (I'm not a fan of global variables)?
It is Ruby, thus class variables behavior would not differ in any way.
General rule of class variables - if you're not sure you know you are using class variable right - do not do that. Even if you are sure - you most likely do not need it.

Ruby - Why is it possible to use Instance variables like everywhere

I'm into Ruby on Rails programming for almost 5 weeks now.
I was wondering why people always use instance variables instead of local ones.
I always thought that you would use instance variables only for classes (so these instance variables are the attributes of the class).
But people also use them not only for being attributes of a class. And this is the part where I am getting confused.
For instance, take a look at these lines of codes:
class Foo
def print_a_hello
puts "Hello World"
end
end
#instance_variable = Foo.new
#instance_variable.print_a_hello
# => "Hello World"
locale_variable = Foo.new
locale_variable.print_a_hello
# => "Hello World"
So, who of you got a great explanation for me?
I was wondering why people always use instance variables instead of locale ones.
I'm not sure how you get that impression. I certainly don't "always" use instance variables. I use instance variables when I need an instance variable, and I use local variables, when I need a local variable, and most code I see does it the same way.
Usually, it doesn't even make sense to interchange them. They have completely different purpose: local variables have static lexical scope, instance variables have dynamic object scope. There's pretty much no way to interchange them, except for the very narrow case of a simple single-file procedural script, where the dynamic scope of the top-level main object and the lexical scope of the script body are identical.
I always thought that you would use instance variables only for classes (so these instance variables are the attributes of the class).
No. Instance variables are attributes of the instance (i.e. object), not the class, that's why they are called "instance variables", after all. Class variables are attributes of the class, but class variables are a different beast and only used in very specific circumstances. (Classes are objects (i.e. instances), too, so they can have instance variables as well; there's generally no need to use class variables, which have some weird and un-intuitive properties, unless you specifically need those weird and un-intuitive properties).
For instance, take a look on this short codelines:
class Foo
def print_a_hello
puts "Hello World"
end
end
#instance_variable = Foo.new
#instance_variable.print_a_hello
# => "Hello World"
locale_variable = Foo.new
locale_variable.print_a_hello
# => "Hello World"
This is the case I mentioned above: in this specific case (and only in this case), the dynamic scope of the top-level main object and the static lexical scope of the script body are identical, so it doesn't matter whether you use a local variable of the script body or an instance variable of the main object.
However, if we make just a tiny change to that, by adding a second script and requireing it from the first, that condition will no longer hold, because we now have two separate script bodies and thus two separate script scopes, but still only one top-level object.
The idiomatic way in your example would definitely be to use a local variable, and nobody I know would do otherwise.
Best use case for instance variables is in Controller's when you want to pass parameter to the view.
Then you use something like
class TestController < ActionController::Base
def show
#usable_in_view = Test.first
not_usable_in_view = Test.first
end
end
In your view you can now use #usable_in_view, but cant use variable not_usable_in_view. Most people always use instance variable in controllers even if they do not need them in view, because they do not understand why they need instance variable
Instance variables are used so that they can be accessed in the view page.
Local variables are not accessible in the view. It has become the habit even I sometimes write instance variables though it is not required in the view.:-)
People probably get in the [bad] habit of using instance variables everywhere since it's common in Rails to use them to get information from the controller to the view.
In my own Ruby code I use instance variables only when I need to, local variables otherwise. That's the proper way to use Ruby.

initializing a class with config (yaml), and setting a variable that should be a single instance

I am getting confused as to how to properly set variables in a initializer, I want these to be class level variables, not instance.
And I also want to then create a single instance of another object (it is a connection object, which already has connection pooling built in, so I just need a single reference to it).
My initializer /initializers/my_class.rb
yml = YAML.load_file("#{Rails.root}/config/my_class.yml")
MYMODULE::MyClass.init(yml)
And here is my my_class.rb:
module MYMODULE
class MyClass
def self.init(yml)
#post_url = yml["defaults"]["post_url"]
end
def self.post_url
#post_url
end
# this should be a single instance
def connection_pool
# ???
end
end
end
These class level variables, how can I access them from both class methods and instance methods?
I'm getting wierd behaviour, and I'm confused as to how to reference the post_url from inside of either class methods and instance methods.
I have seen the following ways, unsure which is correct:
self.class.post_url
MyClass.post_url
#post_url
post_url
self.post_url
self.class.post_url or MyClass.post_url will work. The difference is how they work for subclasses (in the former case, subclasses will use their own version of this variable automatically, in the latter, they would share the variable in MyClass).
There is no way to directly access class instance variables from an instance: you have to call a class method which returns (or sets) them. See also: cattr_accessor.
That said, if this is really a singleton, it seems a little strange to me that you would configure part of it on the class, and then reference that info in the (single) instance. Wouldn't it make more sense just to configure this stuff on the instance? Or use a module as a singleton and not create an instance at all?

Rails: what are the main reasons for making methods private?

If the end_user cannot access the source code of the app, why we still need to make some methods private?
I'm reading the Pragmatic Agile Web Development with Rails and I couldn't understand why we need to make the following method private (even after reading the explanation):
private
def current_cart Cart.find(session[:cart_id])
rescue ActiveRecord::RecordNotFound
cart = Cart.create
session[:cart_id] = cart.id
cart
end
end
It says that it will never allow Rails to make it available as an action, but as a coder, why would I ever do that myself?
As you say there may be no external reason to make it private. However, it also prevents you — or somebody else using your code — from accidentally making use of the method where you're not supposed to.
See it as a sanity check on your own future behaviour if you will.
It aims to encourage good practices and good code.
The idea is that you have two separate parts to your code:
"Above the line" (Public). This is the interface to the rest of the world. This is the API, where calls are made when using instances of the object. Once created, you know that THIS is the area where changes can affect current usages of the code.
"Below the line (Private). This is where detailed logic resides. This code can be changed and refactored freely without any affect to the public interface.
It may help guide your test writing
Private methods may or may not be (unit) tested.
Public methods are more encouraging of both unit and integrated tests as the fact that is is public means that it is serving as the public face for that code and as it is public it might be called from any other point in the future, so having good tests to make sure it continues to work as advertised is essential.
It may help with security as you have greater control who calls private methods (i.e. only public methods in the same class calling them).
It may help reduce name collisions as you have less names in the public space.
End user might not be able to access your code but someone else in your team can definitely access it and they might change it.
The other benefit of encapsulation is that it allows one class ("server") to make a contract with another class ("client") to provide some service with only a very few things being required to be known about the "server" class such as method signature and return type. The benefit is only realized if the contract of what is required and what is returned remains the same. So, in your example, there is no benefit since the contract was broken by Class A.
Instead of class A changing int type to float, class A should create another new variable of type float for other classes to use so that class B is not "broken" or that contract is not broken between them. Class C could refer to new float variable and Class B could still refer to old int variable and everyone is happy. Better yet, methods would used to retrieve values such as: "getUsersAddress" and "getUSersPhoneNumber" depending on what was wanted.
The real benefit of good encapsulation is that Class A can be completely re-written from top to bottom and as long as the contract is honored as to what Class A is expected to do(have methods "getUsersAddress" and "getUSersPhoneNumber"), then everything in Class B and C works the same. Think carefully about what is exposed and how it is exposed. Things that will change often and break other classes need to be considered carefully before exposing. Good encapsulation means hiding things that are expected to change often so to avoid breaking other classes.
It says that it will never allow Rails to make it available as an action,
Hmm, is this in a Rails Conroller class? And is the book you are working through written for Rails 2.x?
In Rails 2.x, by default any public method in a Controller can be triggered by someone accessing the url /name_of_controller/name_of_method .
But there are some methods in your controller that you don't want anyone on the web to trigger, they weren't intended as 'action methods'. So in Rails 2.x, you mark those as protected or private, something not public. "action method" means a method you intend to be directly triggered via a URL.
In Rails 3.x, routing has generally changed such that only certain methods you explicitly route to are available to be triggered via a URL. However, it might still make sense to mark non-action-methods in a Controller as protected or private so:
It's more clear from skimming the source which methods are action methods and which aren't
As a precaution in case someone changes the routing in such a way that would allow a URL to trigger those methods not intended as action methods
Or for general reasons of code organization that other answers mention, that are not specific to Rails controller classes.
There are several reasons as mentioned above. The interesting thing about this encapsulation in ruby is that it can be violated.
See the "send" method and its brother "public_send".
And for a very common metaprogramming technique that uses this method see:
dynamic finders

Resources