Martin Edenhofer 10 лет назад
Родитель
Сommit
014ff4bda2

+ 9 - 9
app/controllers/sessions/collection_base.rb

@@ -19,16 +19,16 @@ module ExtraCollection
   def push( collections, user )
 
     # all base stuff
-    collections[ Role.to_app_model ]          = Role.all
-    collections[ Group.to_app_model ]         = Group.all
+    #collections[ Role.to_app_model ]          = Role.all
+    #collections[ Group.to_app_model ]         = Group.all
 
-    if !user.is_role('Customer')
-      collections[ Organization.to_app_model ]  = Organization.all
-    else
-      if user.organization_id
-        collections[ Organization.to_app_model ]  = Organization.where( :id => user.organization_id )
-      end
-    end
+    #if !user.is_role('Customer')
+    #  collections[ Organization.to_app_model ]  = Organization.all
+    #else
+    #  if user.organization_id
+    #    collections[ Organization.to_app_model ]  = Organization.where( :id => user.organization_id )
+    #  end
+    #end
   end
   module_function :session, :push
 end

+ 9 - 9
app/controllers/sessions/collection_ticket.rb

@@ -22,20 +22,20 @@ module ExtraCollection
   def push( collections, user )
 
     # all ticket stuff
-    collections[ Ticket::StateType.to_app_model ]       = Ticket::StateType.all
-    collections[ Ticket::State.to_app_model ]           = Ticket::State.all
-    collections[ Ticket::Priority.to_app_model ]        = Ticket::Priority.all
-    collections[ Ticket::Article::Type.to_app_model ]   = Ticket::Article::Type.all
-    collections[ Ticket::Article::Sender.to_app_model ] = Ticket::Article::Sender.all
+    #collections[ Ticket::StateType.to_app_model ]       = Ticket::StateType.all
+    #collections[ Ticket::State.to_app_model ]           = Ticket::State.all
+    #collections[ Ticket::Priority.to_app_model ]        = Ticket::Priority.all
+    #collections[ Ticket::Article::Type.to_app_model ]   = Ticket::Article::Type.all
+    #collections[ Ticket::Article::Sender.to_app_model ] = Ticket::Article::Sender.all
 
-    if !user.is_role('Customer')
+    #if !user.is_role('Customer')
 
       # all signatures
-      collections[ Signature.to_app_model ]     = Signature.all
+    #  collections[ Signature.to_app_model ]     = Signature.all
 
       # all email addresses
-      collections[ EmailAddress.to_app_model ]  = EmailAddress.all
-    end
+    #  collections[ EmailAddress.to_app_model ]  = EmailAddress.all
+    #end
   end
 
   module_function :session, :push

+ 1 - 1
app/models/recent_view.rb

@@ -37,7 +37,7 @@ class RecentView < ApplicationModel
       data.delete( 'history_object_id' )
       list.push data
     }
-    return list
+    list
   end
 
   def self.list_fulldata( user, limit = 10 )

+ 1 - 80
lib/sessions.rb

@@ -14,7 +14,6 @@ module Sessions
   @pid  = @root + '/tmp/pids/sessionworker.pid'
 
   # create global vars for threads
-  @@user_threads = {}
   @@client_threads = {}
 
 =begin
@@ -458,23 +457,6 @@ returns
         user = User.find( session_data[:user][:id] )
         next if !user
 
-        # start user thread
-        start_user_thread = false
-        if !@@user_threads[user.id]
-          @@user_threads[user.id] = true
-          @@user_threads[user.id] = Thread.new {
-            thread_worker(user.id)
-            @@user_threads[user.id] = nil
-            puts "close user (#{user.id}) thread"
-          }
-          start_user_thread = true
-        end
-
-        # wait with client thread unil user thread has done some little work
-        if start_user_thread
-          sleep 0.5
-        end
-
         # start client thread
         if !@@client_threads[client_id]
           @@client_threads[client_id] = true
@@ -493,68 +475,6 @@ returns
 
 =begin
 
-check if worker for user is running
-
-  Sessions.thread_worker_exists?(user)
-
-returns
-
-  thread
-
-=end
-
-  def self.thread_worker_exists?(user)
-    @@user_threads[user.id]
-  end
-
-=begin
-
-start worker for user
-
-  Sessions.thread_worker(user.id)
-
-returns
-
-  thread
-
-=end
-
-  def self.thread_worker(user_id, try_count = 0, try_run_time = Time.now)
-    puts "LOOP WORKER #{user_id} - #{try_count}"
-    begin
-      Sessions::Worker.new(user_id)
-    rescue => e
-      puts "thread_worker exited with error #{ e.inspect }"
-      sleep 10
-      begin
-#        ActiveRecord::Base.remove_connection
-#        ActiveRecord::Base.connection_pool.reap
-        ActiveRecord::Base.connection_pool.release_connection
-      rescue => e
-        puts "Can't reconnect to database #{ e.inspect }"
-      end
-
-      try_run_max = 10
-      try_count += 1
-
-      # reset error counter if to old
-      if try_run_time + ( 60 * 5 ) < Time.now
-        try_count = 0
-      end
-      try_run_time = Time.now
-
-      # restart worker again
-      if try_run_max > try_count
-        thread_worker(user_id, try_count, try_run_time)
-      else
-        raise "STOP thread_worker for user #{user_id} after #{try_run_max} tries"
-      end
-    end
-    puts "/LOOP WORKER #{user_id} - #{try_count}"
-  end
-
-=begin
-
 check if thread for client_id is running
 
   Sessions.thread_client_exists?(client_id)
@@ -587,6 +507,7 @@ returns
       Sessions::Client.new(client_id)
     rescue => e
       puts "thread_client exited with error #{ e.inspect }"
+      puts e.backtrace.join("\n  ")
       sleep 10
       begin
 #        ActiveRecord::Base.remove_connection

+ 53 - 28
lib/sessions/backend/activity_stream.rb

@@ -1,38 +1,63 @@
-module Sessions::Backend::ActivityStream
-
-  def self.worker( user, worker )
-    cache_key = 'user_' + user.id.to_s + '_activity_stream'
-    if Sessions::CacheIn.expired(cache_key)
-      activity_stream = user.activity_stream( 20 )
-      activity_stream_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } )
-      worker.log 'notice', 'fetch activity_stream - ' + cache_key
-      if activity_stream != activity_stream_cache
-        worker.log 'notify', 'fetch activity_stream changed - ' + cache_key
-
-        activity_stream_full = user.activity_stream( 20, true )
-        Sessions::CacheIn.set( cache_key, activity_stream, { :expires_in => 0.75.minutes } )
-        Sessions::CacheIn.set( cache_key + '_push', activity_stream_full )
-      end
+class Sessions::Backend::ActivityStream
+
+  def initialize( user, client = nil, client_id = nil )
+    @user         = user
+    @client       = client
+    @client_id    = client_id
+    @last_change  = nil
+  end
+
+  def load
+
+    # get whole collection
+    activity_stream = @user.activity_stream( 25 )
+    if activity_stream && !activity_stream.first
+      return
+    end
+
+    if activity_stream && activity_stream.first && activity_stream.first['created_at'] == @last_change
+      return
+    end
+
+    # update last changed
+    if activity_stream && activity_stream.first
+       @last_change = activity_stream.first['created_at']
     end
+
+    @user.activity_stream( 25, true )
+  end
+
+  def client_key
+    "as::load::#{ self.class.to_s }::#{ @user.id }::#{ @client_id }"
   end
 
-  def self.push( user, client )
-    cache_key = 'user_' + user.id.to_s + '_activity_stream'
+  def push
+
+    # check timeout
+    timeout = Sessions::CacheIn.get( self.client_key )
+    return if timeout
 
-    activity_stream_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } )
-    if activity_stream_time && client.last_change['activity_stream'] != activity_stream_time
-      client.last_change['activity_stream'] = activity_stream_time
-      activity_stream = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } )
-      client.log 'notify', "push activity_stream for user #{user.id}"
+    # set new timeout
+    Sessions::CacheIn.set( self.client_key, true, { :expires_in => 0.5.minutes } )
 
-      # send update to browser
-      r = Sessions::CacheIn.get( cache_key + '_push', { :ignore_expire => true } )
-      client.send({
+    data = self.load
+
+    return if !data||data.empty?
+
+    if !@client
+      return {
         :event      => 'activity_stream_rebuild',
-        :collection => 'activity_stream', 
-        :data       => r,
-      })
+        :collection => 'activity_stream',
+        :data       => data,
+      }
     end
+
+    @client.log 'notify', "push activity_stream #{ data.first.class.to_s } for user #{ @user.id }"
+    @client.send({
+      :event      => 'activity_stream_rebuild',
+      :collection => 'activity_stream',
+      :data       => data,
+    })
   end
 
 end

+ 35 - 59
lib/sessions/backend/collections.rb

@@ -1,71 +1,47 @@
-module Sessions::Backend::Collections
-  @@last_change = {}
+class Sessions::Backend::Collections
 
-  def self.worker( user, worker )
-
-    worker.log 'notice', "---user - fetch push_collection data"
-
-    # get available collections
-    cache_key = 'user_' + user.id.to_s + '_push_collections'
-    collections = Sessions::CacheIn.get( cache_key )
-    if !collections
-      collections = {}
-      push_collection = SessionHelper::push_collections(user)
-      push_collection.each { | key, value |
-        collections[ key ] = true
-      }
-      Sessions::CacheIn.set( cache_key, collections, { :expires_in => 2.minutes } )
-    end
+  def initialize( user, client, client_id )
+    @user       = user
+    @client     = client
+    @client_id  = client_id
+    @backends   = self.backend
+  end
 
-    # check all collections to push
-    push_collection = {}
-    collections.each { | key, v |
-      cache_key = 'user_' + user.id.to_s + '_push_collections_' + key.to_s
-      if Sessions::CacheIn.expired(cache_key)
-        if push_collection.empty?
-          push_collection = SessionHelper::push_collections(user)
-        end
-        push_collection_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } )
-        worker.log 'notice', "---user - fetch push_collection data " + cache_key
-#        if !push_collection[key] || !push_collection_cache || push_collection[key] != push_collection_cache || !push_collection[ key ].zip( push_collection_cache ).all? { |x, y| x.attributes == y.attributes }
-        if !push_collection[key] || !push_collection_cache || push_collection[key] != push_collection_cache || !push_collection[ key ].zip( push_collection_cache ).all? { |x, y| return false if !x; return false if !y; x.attributes == y.attributes }
 
-          worker.log 'notify', 'fetch push_collection changed - ' + cache_key
-          Sessions::CacheIn.set( cache_key, push_collection[key], { :expires_in => 1.minutes } )
-        end
+  def push
+    results = []
+    @backends.each {|backend|
+      #puts "B: #{backend.inspect}"
+      result = backend.push
+      #puts "R: #{result.inspect}"
+      if result
+        results.push result
       end
     }
-
+    results
   end
 
-  def self.push( user, client )
-
-    cache_key = 'user_' + user.id.to_s + '_push_collections'
-    if !client.last_change['push_collections']
-      client.last_change['push_collections'] = {}
+  def backend
+
+    # auto population collections
+    backends = []
+
+    # load collections to deliver from external files
+    dir = File.expand_path('../../../../', __FILE__)
+    files = Dir.glob( "#{dir}/lib/sessions/backend/collections/*.rb" )
+    for file in files
+      file.gsub!("#{dir}/lib/", '')
+      file.gsub!(/\.rb$/, '')
+      next if file.classify == 'Sessions::Backend::Collections::Base'
+      #puts "LOAD #{file.classify}---"
+      #next if file == ''
+      backend = file.classify.constantize.new(@user, @client, @client_id)
+      if backend
+        backends.push backend
+      end
     end
 
-    collections = Sessions::CacheIn.get( cache_key ) || {}
-    collections.each { | key, v |
-      collection_cache_key = 'user_' + user.id.to_s + '_push_collections_' + key.to_s
-      collection_time = Sessions::CacheIn.get_time( collection_cache_key, { :ignore_expire => true } )
-      if collection_time && client.last_change['push_collections'][ key ] != collection_time
-
-        client.last_change['push_collections'][ key ] = collection_time
-        push_collections = Sessions::CacheIn.get( collection_cache_key, { :ignore_expire => true } )
-
-        client.log 'notify', "push push_collections #{key} for user #{user.id}"
-
-        # send update to browser
-        data = {}
-        data[key] = push_collections
-        client.send({
-          :event  => 'resetCollection',
-          :data   => data,
-        })
-
-      end
-    }
+    backends
   end
 
 end

+ 137 - 0
lib/sessions/backend/collections/base.rb

@@ -0,0 +1,137 @@
+class Sessions::Backend::Collections::Base
+  class << self; attr_accessor :model, :is_role, :is_not_role end
+
+  def initialize( user, client = nil, client_id = nil )
+    @user         = user
+    @client       = client
+    @client_id    = client_id
+    @last_change  = nil
+  end
+
+  def collection_key
+    "collections::load::#{ self.class.to_s }::#{ @user.id }"
+  end
+
+  def load
+#puts "-LOAD--------#{self.collection_key}"
+    # check timeout
+    cache = Sessions::CacheIn.get( self.collection_key )
+    return cache if @last_change && cache
+#puts "---REAL FETCH #{@user.id}"
+    # update last changed
+    last = self.class.model.constantize.select('updated_at').order('updated_at DESC').first
+    if last
+      @last_change = last.updated_at
+    end
+
+    # if no entry exists, remember last check
+    if !@last_change
+      @last_change = Time.now
+    end
+
+    # get whole collection
+    all = self.class.model.constantize.all
+
+    # set new timeout
+    Sessions::CacheIn.set( self.collection_key, all, { :expires_in => 10.minutes } )
+
+    all
+  end
+
+  def changed?
+    # if no data has been delivered till now
+    return true if !@last_change
+
+    # check if update has been done
+    last = self.class.model.constantize.select('updated_at').order('updated_at DESC').first
+    return false if !last
+    return false if last.updated_at == @last_change
+
+    # delete collection cache
+    Sessions::CacheIn.delete( self.collection_key )
+
+    # collection has changed
+    true
+  end
+
+  def client_key
+    "collections::load::#{ self.class.to_s }::#{ @user.id }::#{ @client_id }"
+  end
+
+  def push
+
+    # check role based access
+    if self.class.is_role
+      access = nil
+      self.class.is_role.each {|role|
+        if @user.is_role(role)
+          access = true
+        end
+      }
+      return if !access
+    end
+    if self.class.is_not_role
+      self.class.is_not_role.each {|role|
+        return if @user.is_role(role)
+      }
+    end
+
+    # check timeout
+    timeout = Sessions::CacheIn.get( self.client_key )
+    return if timeout
+
+    # set new timeout
+    Sessions::CacheIn.set( self.client_key, true, { :expires_in => 10.seconds } )
+
+    return if !self.changed?
+    data = self.load
+
+    return if !data||data.empty?
+
+    # collect assets
+    assets = {}
+    data.each {|item|
+      assets = item.assets(assets)
+    }
+    if !@client
+      return {
+        :collection => {
+          data.first.class.to_app_model => data,
+        },
+        :assets => assets,
+      }
+    end
+    @client.log 'notify', "push assets for push_collection #{ data.first.class.to_s } for user #{ @user.id }"
+    @client.send({
+      :data   => assets,
+      :event  => [ 'loadAssets' ],
+    })
+
+    @client.log 'notify', "push push_collection #{ data.first.class.to_s } for user #{ @user.id }"
+    @client.send({
+      :event  => 'resetCollection',
+      :data   => {
+        data.first.class.to_app_model => data,
+      },
+    })
+  end
+
+  def self.model_set(model)
+    @model = model
+  end
+
+  def self.is_role_set(role)
+    if !@is_role
+      @is_role = []
+    end
+    @is_role.push role
+  end
+
+  def self.is_not_role_set(role)
+    if !@is_not_role
+      @is_not_role = []
+    end
+    @is_not_role.push role
+  end
+
+end

+ 4 - 0
lib/sessions/backend/collections/email_address.rb

@@ -0,0 +1,4 @@
+class Sessions::Backend::Collections::EmailAddress < Sessions::Backend::Collections::Base
+  model_set 'EmailAddress'
+  is_not_role_set 'Customer'
+end

+ 3 - 0
lib/sessions/backend/collections/group.rb

@@ -0,0 +1,3 @@
+class Sessions::Backend::Collections::Group < Sessions::Backend::Collections::Base
+  model_set 'Group'
+end

+ 67 - 0
lib/sessions/backend/collections/organization.rb

@@ -0,0 +1,67 @@
+class Sessions::Backend::Collections::Organization < Sessions::Backend::Collections::Base
+  model_set 'Organization'
+
+  def load
+
+    # check timeout
+    cache = Sessions::CacheIn.get( self.collection_key )
+    return cache if @last_change && cache
+
+    # update last changed
+    if !@user.is_role('Customer')
+      last = self.class.model.constantize.select('updated_at').order('updated_at DESC').first
+      if last
+        @last_change = last.updated_at
+      end
+    else
+      if @user.organization_id
+        last = Organization.where( :id => @user.organization_id ).first
+        @last_change = last.updated_at
+      end
+    end
+
+    # if no entry exists, remember last check
+    if !@last_change
+      @last_change = Time.now
+    end
+
+    # get whole collection
+    all = []
+    if !@user.is_role('Customer')
+      all = Organization.all
+    else
+      if @user.organization_id
+        all = Organization.where( :id => @user.organization_id )
+      end
+    end
+
+    # set new timeout
+    Sessions::CacheIn.set( self.collection_key, all, { :expires_in => 10.minutes } )
+
+    all
+  end
+
+  def changed?
+
+    # if no data has been delivered till now
+    return true if !@last_change
+
+    # check if update has been done
+    if !@user.is_role('Customer')
+      last = self.class.model.constantize.select('updated_at').order('updated_at DESC').first
+    else
+      if @user.organization_id
+        last = Organization.where( :id => @user.organization_id ).first
+      end
+    end
+    return false if !last
+    return false if last.updated_at == @last_change
+
+    # delete collection cache
+    Sessions::CacheIn.delete( self.collection_key )
+
+    # collection has changed
+    true
+  end
+
+end

Некоторые файлы не были показаны из-за большого количества измененных файлов