Nathan Chalot

Joined

3,010 Experience
28 Lessons Completed
0 Questions Solved

Activity

Hi all,
the same thing as Ahmad happened to me, and switching to firefox did not fix the issue.

I don't know why but after some digging I found that the tests were never going back to the top level once inside the second within_frame call:

find_frame('body > div > iframe') do
      sleep 1
      find_frame('#challengeFrame') do
        click_on "Complete authentication"
        # test hang here
      end
    end

To fix it I instead used :

stripe_frame = find('body > div > iframe')
switch_to_frame(stripe_frame) # enter the first frame
auth_frame = find('#challengeFrame')
sleep 2
switch_to_frame(auth_frame) # enter the second frame
sleep 2
click_on "Fail authentication"
switch_to_frame(:top) # go back to the top level

That is manually switching between frames and going back to the top level.

I post that here in case it happens to somebody else.

PS: My SCA confirmation/failure take place inside a Capybara.using_session if that's of any help.

Hi all,
I'm running in a weird issue.

Following the Realtime Online User Tracking with ActionCable screencast, in an app using rails 5.2 I used:

ActionCable.server.pubsub.redis_connection_for_subscriptions.sadd
ActionCable.server.pubsub.redis_connection_for_subscriptions.rem
ActionCable.server.pubsub.redis_connection_for_subscriptions.smembers

to add, remove and retrieve a users ids list from redis.

Deploying to staging on heroku, using the rediscloud addon for redis, I had the following issue with this implementation, each of this call was instantiating a new connexion to redis, so that I was hitting the rediscloud connexion limit really fast.

First:

does anyone has this kind of issue ? I cannot replicate the output I got from redis cloud in redis-cli CLIENT LIST in my local env. So I'm wondering if it has something to do with redis cloud ?

Second:

I read here to use ActionCable.server.pubsub.send(:redis_connection) to get the ActionCable connexion but I looked into the code for the ActionCable Redis adapater and, I'm not totally sure but think that's what the initial method redis_connection_for_subscriptions does.

Does ActionCable.server.pubsub.redis_connection_for_subscriptions indeed instantiate a new connexion each time it is called?

Third:

I'm kind of worried about my current solution:

I resolved the problem by doing inspired by the rediscloud doc this in an initializer

$redis = Redis.new(url: ENV['REDIS_URL')

and replacing the initial code by:

$redis.sadd
$redis.srem
$redis.smembers

It now works as expected and I don't reach the connexion limit, but I'm quite not sure about the use of a global variable.

If anybody has an insight / a better way to solve this I would really appreciate it.

thanks for reading that long post :)

Hi,
I'm asked to make Stripe plans where the user can chose between three plans where pricing depends of the duration:

  • per month (15$/mo)
  • per trimester (12$/mo)
  • per year (10$/mo)

For all this plans the user should be charged each month with the corresponding price.
I cannot charge for the whole period so I'm currently wondering how to do that in a clean way.

What would be a good approach to this problem ?

I was thinking about setting 3 monthly plans and allow user to cancel at anytime but:

  • setting the subscription end_date to today's date + the cycle's remaining period but I think it's going to be quiet complicated to keep track of the current cyle
  • another option coming to my mind is storing the subscrition creation date and minimum allowed cancelation date to then
    • set the subscription end_at to the minimum allowed one if the customer want to unsubscribe before it
    • cancel the subscription at the end of the month if the subscriber want to cancel after the minimum allowed one.

The second option seems simpler to me but does not allow to enforce renewal of minimum cycle (I personnally think it's a good thing).
There is probably a much simpler way but I'm a bit stuck with that.
I think it is (or I am) over complicating things, but as it's a requierement and I must (at least try) to find a solution.

Any advice on this issue would be of great help :)
Thanks

Hi,
I never worked with multy tenancy and I'm also quite new to ActionCable
so I don't really know, but my guess is you could pass an array to identified_by and identify by both current_user and current_tenant.
Then set current_tenant or reject connection if none is found.
I did some testing and the following make the current_tenant variable availble in all channels and seems to work fine.

module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user, :current_tenant

    def connect
      self.current_user = find_verified_user
      self.current_tenant = find_tenant
      logger.add_tags "ActionCable", "#{current_user.class.name} #{current_user.id}"
    end

    protected

    def find_verified_user
      # some logic to find the user
    end

    def find_tenant
      # just an example
      if user.tenant.present?
        user.tenant
      else
        reject_unauthorized_connection
      end
    end
  end
end

Again, I never had to do that so I'm not sure about this solution but it seems to work fine.
Let me know if this i working :)

Hi,
I know it has been a year since this question was asked but I'd like to propose a solution (and get feedback eventually).

IMPORTANT
Note that your channel subscriptions are public, so with the following example somebody could do in the browser console:

App.thins.perform('add_new_thing_stream', { channel: 'whatever'})

and the user will be streaming fron 'whatever'
the ThingChannel#add_new_thing_stream here need more work to prevent users from streaming from whatever they want.
------

Here is the idea of how to do it (in a rails 5.2 app):

# thing_channel.rb
class ThingChannel < ApplicationCable::Channel
  def subscribe
    ...
    stream_from "new_things_for:#{current_user.id}"
    ...
  end
    ...
  def add_new_thing_stream(data)
    stream_from data['channel']
  end
end

# when broadcasting
ActionCable.server.broadcast( "new_chat_rooms_for:#{user.id}", datas....)
# thing.js
App.chatRoom = App.cable.subscriptions.create("ThingChannel", {
...
  received: function(data) {
    ...
    this.perform("add_new_thing_stream", { channel: data.channel } );
    ...
  }
}
...

It's far from perfect but it do the job.

So if anybody has another solution or an opinion about this one, I'd be glad to see it :)

I was wondering about that since that method is called once for each displayed user on the page so it seemed to me that it could cause a N+1 query like problem.
I'll keep it that way then :)
Thanks Chris.

Hi,
I'm wondering on my current implementation for tracking and displaying user online presence.
I followed "Realtime Online User Tracking with ActionCable" for the most part and right now I'm using the following code to show if a particular user is online or not:

class User < ApplicationRecord
  ...
  def is_online?
    ids = ActionCable.server.pubsub.redis_connection_for_subscriptions.smembers "online_users"
    ids.include?(id.to_s)
  end
  ...
end

It's working fine but I'm wondering:

  • is it ok to make a request like this every time I display a user ?
  • or should I instead update a boolean field on the User model on subscribed and unsubscribed methods in the Channel.

Any advice would be of great help.
Thanks :)

Hi Matt,
what about setting a different key per tenant ?

ActionCable.server.pubsub.redis_connection_for_subscriptions.sadd(
        "online_users_account#{account.id}", current_user.id)

As I was facing another (but I think related) issue, storing apperance for multiple models, I store a key per model and each one has its own array.

I don't post so much so first : thanks for the screencast on the site, I find them very valuable :)
I just stumbled upon this screencast, so I know this is an old topic but is there still any plan on this video series about building a web framework ? It would be awesome, either way I found some articles online but if anyone got some resources to point out on this topic I would really enjoy it.