From d2ef07c7594da295d4c1c32071ac35f8cd7ec378 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Sun, 22 Sep 2013 00:40:19 +0200 Subject: [PATCH] Split of web sockets worker and renamed collection names. --- .../app/controllers/ticket_zoom.js.coffee | 2 +- .../app/lib/app_post/collection.js.coffee | 7 + app/controllers/sessions/collection_base.rb | 18 +- .../sessions/collection_network.rb | 16 +- app/controllers/sessions/collection_ticket.rb | 28 +- app/controllers/sessions_controller.rb | 4 +- .../ticket_overviews_controller.rb | 6 +- app/controllers/tickets_controller.rb | 24 +- app/models/history/assets.rb | 20 +- app/models/organization/assets.rb | 18 +- app/models/ticket/article/assets.rb | 22 +- app/models/ticket/assets.rb | 28 +- app/models/user/assets.rb | 8 +- lib/core_ext/class.rb | 6 +- lib/sessions.rb | 557 +----------------- lib/sessions/backend.rb | 2 + lib/sessions/backend/activity_stream.rb | 39 ++ lib/sessions/backend/collections.rb | 70 +++ lib/sessions/backend/recent_viewed.rb | 38 ++ lib/sessions/backend/rss.rb | 41 ++ lib/sessions/backend/ticket_create.rb | 48 ++ lib/sessions/backend/ticket_overview_index.rb | 39 ++ lib/sessions/backend/ticket_overview_list.rb | 95 +++ lib/sessions/cache_in.rb | 56 ++ lib/sessions/client.rb | 165 ++++++ lib/sessions/worker.rb | 58 ++ 26 files changed, 763 insertions(+), 652 deletions(-) create mode 100644 lib/sessions/backend.rb create mode 100644 lib/sessions/backend/activity_stream.rb create mode 100644 lib/sessions/backend/collections.rb create mode 100644 lib/sessions/backend/recent_viewed.rb create mode 100644 lib/sessions/backend/rss.rb create mode 100644 lib/sessions/backend/ticket_create.rb create mode 100644 lib/sessions/backend/ticket_overview_index.rb create mode 100644 lib/sessions/backend/ticket_overview_list.rb create mode 100644 lib/sessions/cache_in.rb create mode 100644 lib/sessions/client.rb create mode 100644 lib/sessions/worker.rb diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index 83c97646c..537415ad3 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -72,7 +72,7 @@ class App.TicketZoom extends App.Controller success: (data, status, xhr) => # check if ticket has changed - newTicketRaw = data.assets.tickets[ticket_id] + newTicketRaw = data.assets.Ticket[ticket_id] if @ticketUpdatedAtLastCall && !force # return if ticket hasnt changed diff --git a/app/assets/javascripts/app/lib/app_post/collection.js.coffee b/app/assets/javascripts/app/lib/app_post/collection.js.coffee index df2c55413..4c91a8ff1 100644 --- a/app/assets/javascripts/app/lib/app_post/collection.js.coffee +++ b/app/assets/javascripts/app/lib/app_post/collection.js.coffee @@ -25,18 +25,25 @@ class _collectionSingleton extends Spine.Module for type, collections of data if type is 'users' type = 'User' + throw "BREAK, users" if type is 'tickets' type = 'Ticket' + throw "BREAK, tickets" if type is 'ticket_article' type = 'TicketArticle' + throw "BREAK, ticket_article" if type is 'organization' type = 'Organization' + throw "BREAK, organization" if type is 'history_object' type = 'HistoryObject' + throw "BREAK, history_object" if type is 'history_type' type = 'HistoryType' + throw "BREAK, history_type" if type is 'history_attribute' type = 'HistoryAttribute' + throw "BREAK, history_attribute" @log 'debug', 'loadCollection:trigger', type, collections @load( localStorage: data.localStorage, type: type, data: collections ) diff --git a/app/controllers/sessions/collection_base.rb b/app/controllers/sessions/collection_base.rb index 96deb0f83..3ad1aecad 100644 --- a/app/controllers/sessions/collection_base.rb +++ b/app/controllers/sessions/collection_base.rb @@ -4,29 +4,29 @@ module ExtraCollection def session( collections, user ) # all base stuff - collections['Taskbar'] = Taskbar.where( :user_id => user.id ) - collections['Role'] = Role.all - collections['Group'] = Group.all + collections[ Taskbar.to_online_model ] = Taskbar.where( :user_id => user.id ) + collections[ Role.to_online_model ] = Role.all + collections[ Group.to_online_model ] = Group.all if !user.is_role('Customer') - collections['Organization'] = Organization.all + collections[ Organization.to_online_model ] = Organization.all else if user.organization_id - collections['Organization'] = Organization.where( :id => user.organization_id ) + collections[ Organization.to_online_model ] = Organization.where( :id => user.organization_id ) end end end def push( collections, user ) # all base stuff - collections['Role'] = Role.all - collections['Group'] = Group.all + collections[ Role.to_online_model ] = Role.all + collections[ Group.to_online_model ] = Group.all if !user.is_role('Customer') - collections['Organization'] = Organization.all + collections[ Organization.to_online_model ] = Organization.all else if user.organization_id - collections['Organization'] = Organization.where( :id => user.organization_id ) + collections[ Organization.to_online_model ] = Organization.where( :id => user.organization_id ) end end end diff --git a/app/controllers/sessions/collection_network.rb b/app/controllers/sessions/collection_network.rb index ff2a7d109..2952b2879 100644 --- a/app/controllers/sessions/collection_network.rb +++ b/app/controllers/sessions/collection_network.rb @@ -3,18 +3,18 @@ module ExtraCollection def session( collections, user ) - collections['Network'] = Network.all - collections['NetworkCategory'] = Network::Category.all - collections['NetworkCategoryType'] = Network::Category::Type.all - collections['NetworkPrivacy'] = Network::Privacy.all + collections[ Network.to_online_model ] = Network.all + collections[ Network::Category.to_online_model ] = Network::Category.all + collections[ Network::Category::Type.to_online_model ] = Network::Category::Type.all + collections[ Network::Privacy.to_online_model ] = Network::Privacy.all end def push( collections, user ) - collections['Network'] = Network.all - collections['NetworkCategory'] = Network::Category.all - collections['NetworkCategoryType'] = Network::Category::Type.all - collections['NetworkPrivacy'] = Network::Privacy.all + collections[ Network.to_online_model ] = Network.all + collections[ Network::Category.to_online_model ] = Network::Category.all + collections[ Network::Category::Type.to_online_model ] = Network::Category::Type.all + collections[ Network::Privacy.to_online_model ] = Network::Privacy.all end module_function :session, :push diff --git a/app/controllers/sessions/collection_ticket.rb b/app/controllers/sessions/collection_ticket.rb index 5742c048e..026ccbfcc 100644 --- a/app/controllers/sessions/collection_ticket.rb +++ b/app/controllers/sessions/collection_ticket.rb @@ -4,37 +4,37 @@ module ExtraCollection def session( collections, user ) # all ticket stuff - collections['TicketStateType'] = Ticket::StateType.all - collections['TicketState'] = Ticket::State.all - collections['TicketPriority'] = Ticket::Priority.all - collections['TicketArticleType'] = Ticket::Article::Type.all - collections['TicketArticleSender'] = Ticket::Article::Sender.all + collections[ Ticket::StateType.to_online_model ] = Ticket::StateType.all + collections[ Ticket::State.to_online_model ] = Ticket::State.all + collections[ Ticket::Priority.to_online_model ] = Ticket::Priority.all + collections[ Ticket::Article::Type.to_online_model ] = Ticket::Article::Type.all + collections[ Ticket::Article::Sender.to_online_model ] = Ticket::Article::Sender.all if !user.is_role('Customer') # all signatures - collections['Signature'] = Signature.all + collections[ Signature.to_online_model ] = Signature.all # all email addresses - collections['EmailAddress'] = EmailAddress.all + collections[ EmailAddress.to_online_model ] = EmailAddress.all end end def push( collections, user ) # all ticket stuff - collections['TicketStateType'] = Ticket::StateType.all - collections['TicketState'] = Ticket::State.all - collections['TicketPriority'] = Ticket::Priority.all - collections['TicketArticleType'] = Ticket::Article::Type.all - collections['TicketArticleSender'] = Ticket::Article::Sender.all + collections[ Ticket::StateType.to_online_model ] = Ticket::StateType.all + collections[ Ticket::State.to_online_model ] = Ticket::State.all + collections[ Ticket::Priority.to_online_model ] = Ticket::Priority.all + collections[ Ticket::Article::Type.to_online_model ] = Ticket::Article::Type.all + collections[ Ticket::Article::Sender.to_online_model ] = Ticket::Article::Sender.all if !user.is_role('Customer') # all signatures - collections['Signature'] = Signature.all + collections[ Signature.to_online_model ] = Signature.all # all email addresses - collections['EmailAddress'] = EmailAddress.all + collections[ EmailAddress.to_online_model ] = EmailAddress.all end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index e5ed41b76..28cfbd186 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -160,8 +160,8 @@ class SessionsController < ApplicationController end } render :json => { - :sessions => sessions_clean, - :users => users, + :sessions => sessions_clean, + User.to_online_model.to_sym => users, } end diff --git a/app/controllers/ticket_overviews_controller.rb b/app/controllers/ticket_overviews_controller.rb index 9433334c4..da931a1a3 100644 --- a/app/controllers/ticket_overviews_controller.rb +++ b/app/controllers/ticket_overviews_controller.rb @@ -49,7 +49,7 @@ class TicketOverviewsController < ApplicationController end # get related users - assets = { :users => {} } + assets = { User.to_online_model.to_sym => {} } overview[:ticket_ids].each {|ticket_id| ticket = Ticket.lookup( :id => ticket_id ) assets = ticket.assets(assets) @@ -70,8 +70,8 @@ class TicketOverviewsController < ApplicationController Group.find(group_id).users.each {|user| next if !agents[ user.id ] groups_users[ group_id ].push user.id - if !assets[:users][user.id] - assets[:users][user.id] = User.user_data_full(user.id) + if !assets[ User.to_online_model.to_sym ][user.id] + assets[ User.to_online_model.to_sym ][user.id] = User.user_data_full(user.id) end } } diff --git a/app/controllers/tickets_controller.rb b/app/controllers/tickets_controller.rb index fe1c5dc08..9e3b5c023 100644 --- a/app/controllers/tickets_controller.rb +++ b/app/controllers/tickets_controller.rb @@ -304,22 +304,22 @@ class TicketsController < ApplicationController # get related users assets = {} - assets[:users] = {} + assets[ User.to_online_model.to_sym ] = {} assets = ticket.assets(assets) # get attributes to update attributes_to_change = Ticket::ScreenOptions.attributes_to_change( :user => current_user, :ticket => ticket ) attributes_to_change[:owner_id].each { |user_id| - if !assets[:users][user_id] - assets[:users][user_id] = User.user_data_full( user_id ) + if !assets[ User.to_online_model.to_sym ][user_id] + assets[ User.to_online_model.to_sym ][user_id] = User.user_data_full( user_id ) end } attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| user_ids.each {|user_id| - if !assets[:users][user_id] - assets[:users][user_id] = User.user_data_full( user_id ) + if !assets[ User.to_online_model.to_sym ][user_id] + assets[ User.to_online_model.to_sym ][user_id] = User.user_data_full( user_id ) end } } @@ -362,17 +362,17 @@ class TicketsController < ApplicationController ) assets = {} - assets[:users] = {} + assets[ User.to_online_model.to_sym ] = {} attributes_to_change[:owner_id].each { |user_id| - if !assets[:users][user_id] - assets[:users][user_id] = User.user_data_full( user_id ) + if !assets[ User.to_online_model.to_sym ][user_id] + assets[ User.to_online_model.to_sym ][user_id] = User.user_data_full( user_id ) end } attributes_to_change[:group_id__owner_id].each {|group_id, user_ids| user_ids.each {|user_id| - if !assets[:users][user_id] - assets[:users][user_id] = User.user_data_full( user_id ) + if !assets[ User.to_online_model.to_sym ][user_id] + assets[ User.to_online_model.to_sym ][user_id] = User.user_data_full( user_id ) end } } @@ -387,8 +387,8 @@ class TicketsController < ApplicationController owner_ids = [] ticket.agent_of_group.each { |user| owner_ids.push user.id - if !assets[:users][user.id] - assets[:users][user.id] = User.user_data_full( user.id ) + if !assets[ User.to_online_model.to_sym ][user.id] + assets[ User.to_online_model.to_sym ][user.id] = User.user_data_full( user.id ) end } diff --git a/app/models/history/assets.rb b/app/models/history/assets.rb index b81d94ef4..d42283307 100644 --- a/app/models/history/assets.rb +++ b/app/models/history/assets.rb @@ -22,22 +22,22 @@ returns def assets (data) - if !data[:users] - data[:users] = {} + if !data[ User.to_online_model.to_sym ] + data[ User.to_online_model.to_sym ] = {} end - if !data[:users][ self['created_by_id'] ] - data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) + if !data[ User.to_online_model.to_sym ][ self['created_by_id'] ] + data[ User.to_online_model.to_sym ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) end # fetch meta relations - if !data[:history_object] - data[:history_object] = History::Object.all() + if !data[ History::Object.to_online_model.to_sym ] + data[ History::Object.to_online_model.to_sym ] = History::Object.all() end - if !data[:history_type] - data[:history_type] = History::Type.all() + if !data[ History::Type.to_online_model.to_sym ] + data[ History::Type.to_online_model.to_sym ] = History::Type.all() end - if !data[:history_attribute] - data[:history_attribute] = History::Attribute.all() + if !data[ History::Attribute.to_online_model.to_sym ] + data[ History::Attribute.to_online_model.to_sym ] = History::Attribute.all() end data diff --git a/app/models/organization/assets.rb b/app/models/organization/assets.rb index c3818915c..11cb0e55b 100644 --- a/app/models/organization/assets.rb +++ b/app/models/organization/assets.rb @@ -22,19 +22,19 @@ returns def assets (data) - if !data[:organizations] - data[:organizations] = {} + if !data[ Organization.to_online_model.to_sym ] + data[ Organization.to_online_model.to_sym ] = {} end - if !data[:users] - data[:users] = {} + if !data[ User.to_online_model.to_sym ] + data[ User.to_online_model.to_sym ] = {} end - if !data[:organizations][ self.id ] - data[:organizations][ self.id ] = self.attributes - data[:organizations][ self.id ][:user_ids] = [] + if !data[ Organization.to_online_model.to_sym ][ self.id ] + data[ Organization.to_online_model.to_sym ][ self.id ] = self.attributes + data[ Organization.to_online_model.to_sym ][ self.id ][:user_ids] = [] users = User.where( :organization_id => self.id ).limit(10) users.each {|user| - data[:users][ user.id ] = User.user_data_full( user.id ) - data[:organizations][ self.id ][:user_ids].push user.id + data[ User.to_online_model.to_sym ][ user.id ] = User.user_data_full( user.id ) + data[ Organization.to_online_model.to_sym ][ self.id ][:user_ids].push user.id } end data diff --git a/app/models/ticket/article/assets.rb b/app/models/ticket/article/assets.rb index 6b8d0e117..8515e475c 100644 --- a/app/models/ticket/article/assets.rb +++ b/app/models/ticket/article/assets.rb @@ -23,24 +23,24 @@ returns def assets (data) - if !data[:ticket_article] - data[:ticket_article] = {} + if !data[ Ticket::Article.to_online_model.to_sym ] + data[ Ticket::Article.to_online_model.to_sym ] = {} end - if !data[:ticket_article][ self.id ] - data[:ticket_article][ self.id ] = self.attributes + if !data[ Ticket::Article.to_online_model.to_sym ][ self.id ] + data[ Ticket::Article.to_online_model.to_sym ][ self.id ] = self.attributes # add attachment list to article - data[:ticket_article][ self.id ]['attachments'] = Store.list( :object => 'Ticket::Article', :o_id => self.id ) + data[ Ticket::Article.to_online_model.to_sym ][ self.id ]['attachments'] = Store.list( :object => 'Ticket::Article', :o_id => self.id ) end - if !data[:users] - data[:users] = {} + if !data[ User.to_online_model.to_sym ] + data[ User.to_online_model.to_sym ] = {} end - if !data[:users][ self['created_by_id'] ] - data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) + if !data[ User.to_online_model.to_sym ][ self['created_by_id'] ] + data[ User.to_online_model.to_sym ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) end - if !data[:users][ self['updated_by_id'] ] - data[:users][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] ) + if !data[ User.to_online_model.to_sym ][ self['updated_by_id'] ] + data[ User.to_online_model.to_sym ][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] ) end data end diff --git a/app/models/ticket/assets.rb b/app/models/ticket/assets.rb index 7b96346ec..87584b48b 100644 --- a/app/models/ticket/assets.rb +++ b/app/models/ticket/assets.rb @@ -23,27 +23,27 @@ returns def assets (data) - if !data[:tickets] - data[:tickets] = {} + if !data[ Ticket.to_online_model.to_sym ] + data[ Ticket.to_online_model.to_sym ] = {} end - if !data[:tickets][ self.id ] - data[:tickets][ self.id ] = self.attributes + if !data[ Ticket.to_online_model.to_sym ][ self.id ] + data[ Ticket.to_online_model.to_sym ][ self.id ] = self.attributes end - if !data[:users] - data[:users] = {} + if !data[ User.to_online_model.to_sym ] + data[ User.to_online_model.to_sym ] = {} end - if !data[:users][ self['owner_id'] ] - data[:users][ self['owner_id'] ] = User.user_data_full( self['owner_id'] ) + if !data[ User.to_online_model.to_sym ][ self['owner_id'] ] + data[ User.to_online_model.to_sym ][ self['owner_id'] ] = User.user_data_full( self['owner_id'] ) end - if !data[:users][ self['customer_id'] ] - data[:users][ self['customer_id'] ] = User.user_data_full( self['customer_id'] ) + if !data[ User.to_online_model.to_sym ][ self['customer_id'] ] + data[ User.to_online_model.to_sym ][ self['customer_id'] ] = User.user_data_full( self['customer_id'] ) end - if !data[:users][ self['created_by_id'] ] - data[:users][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) + if !data[ User.to_online_model.to_sym ][ self['created_by_id'] ] + data[ User.to_online_model.to_sym ][ self['created_by_id'] ] = User.user_data_full( self['created_by_id'] ) end - if !data[:users][ self['updated_by_id'] ] - data[:users][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] ) + if !data[ User.to_online_model.to_sym ][ self['updated_by_id'] ] + data[ User.to_online_model.to_sym ][ self['updated_by_id'] ] = User.user_data_full( self['updated_by_id'] ) end data end diff --git a/app/models/user/assets.rb b/app/models/user/assets.rb index 202303355..3425b7f0a 100644 --- a/app/models/user/assets.rb +++ b/app/models/user/assets.rb @@ -22,11 +22,11 @@ returns def assets (data) - if !data[:users] - data[:users] = {} + if !data[ User.to_online_model.to_sym ] + data[ User.to_online_model.to_sym ] = {} end - if !data[:users][ self.id ] - data[:users][ self.id ] = User.user_data_full( self.id ) + if !data[ User.to_online_model.to_sym ][ self.id ] + data[ User.to_online_model.to_sym ][ self.id ] = User.user_data_full( self.id ) end data end diff --git a/lib/core_ext/class.rb b/lib/core_ext/class.rb index b1c3c4695..962d2182e 100644 --- a/lib/core_ext/class.rb +++ b/lib/core_ext/class.rb @@ -7,4 +7,8 @@ class Class tr("-", "_"). downcase end -end + def to_online_model + camel_cased_word = self.to_s + camel_cased_word.gsub(/::/, '') + end +end \ No newline at end of file diff --git a/lib/sessions.rb b/lib/sessions.rb index e8d5402b0..889535d96 100644 --- a/lib/sessions.rb +++ b/lib/sessions.rb @@ -217,7 +217,7 @@ module Sessions if !@@user_threads[user.id] start_user_thread = true @@user_threads[user.id] = Thread.new { - UserState.new(user.id) + Sessions::Worker.new(user.id) @@user_threads[user.id] = nil puts "close user(#{user.id}) thread" # raise "Exception from thread" @@ -232,7 +232,7 @@ module Sessions # start client thread if !@@client_threads[client_id] @@client_threads[client_id] = Thread.new { - ClientState.new(client_id) + Sessions::Client.new(client_id) @@client_threads[client_id] = nil puts "close client(#{client_id}) thread" # raise "Exception from thread" @@ -307,555 +307,4 @@ module Sessions FileUtils.rm_rf path end -end - -module CacheIn - @@data = {} - @@data_time = {} - @@expires_in = {} - @@expires_in_ttl = {} - - def self.set( key, value, params = {} ) -# puts 'CacheIn.set:' + key + '-' + value.inspect - if params[:expires_in] - @@expires_in[key] = Time.now + params[:expires_in] - @@expires_in_ttl[key] = params[:expires_in] - end - @@data[ key ] = value - @@data_time[ key ] = Time.now - end - - def self.expired( key, params = {} ) - - # expire if value never was set - return true if !@@data.include? key - - # ignore_expire - return false if params[:ignore_expire] - - # set re_expire - if params[:re_expire] - if @@expires_in[key] - @@expires_in[key] = Time.now + @@expires_in_ttl[key] - end - return false - end - - # check if expired - if @@expires_in[key] - return true if @@expires_in[key] < Time.now - return false - end - - # return false if key was set without expires_in - return false - end - - def self.get_time( key, params = {} ) - data = self.get( key, params ) - if data - return @@data_time[key] - end - return nil - end - - def self.get( key, params = {} ) -# puts 'CacheIn.get:' + key + '-' + @@data[ key ].inspect - return if self.expired( key, params ) - @@data[ key ] - end -end - - -class UserState - def initialize( user_id ) - @user_id = user_id - @data = {} - @cache_key = 'user_' + user_id.to_s - self.log 'notify', "---user started user state" - - CacheIn.set( 'last_run_' + user_id.to_s , true, { :expires_in => 20.seconds } ) - - self.fetch - end - - def fetch - user = User.find( @user_id ) - return if !user - - while true - - # check if user is still with min one open connection - if !CacheIn.get( 'last_run_' + user.id.to_s ) - self.log 'notify', "---user - closeing thread - no open user connection" - return - end - - self.log 'notice', "---user - fetch user data" - # overview - cache_key = @cache_key + '_overview' - if CacheIn.expired(cache_key) - overview = Ticket::Overviews.list( - :current_user => user, - ) - overview_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch overview - ' + cache_key - if overview != overview_cache - self.log 'notify', 'fetch overview changed - ' + cache_key -# puts overview.inspect -# puts '------' -# puts overview_cache.inspect - CacheIn.set( cache_key, overview, { :expires_in => 4.seconds } ) - end - end - - # overview lists - overviews = Ticket::Overviews.all( - :current_user => user, - ) - overviews.each { |overview| - cache_key = @cache_key + '_overview_data_' + overview.link - if CacheIn.expired(cache_key) - overview_data = Ticket::Overviews.list( - :view => overview.link, - :current_user => user, - :array => true, - ) - overview_data_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch overview_data - ' + cache_key - if overview_data != overview_data_cache - self.log 'notify', 'fetch overview_data changed - ' + cache_key - CacheIn.set( cache_key, overview_data, { :expires_in => 5.seconds } ) - end - end - } - - # create_attributes - cache_key = @cache_key + '_ticket_create_attributes' - if CacheIn.expired(cache_key) - ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change( - :current_user_id => user.id, - ) - ticket_create_attributes_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch ticket_create_attributes - ' + cache_key - if ticket_create_attributes != ticket_create_attributes_cache - self.log 'notify', 'fetch ticket_create_attributes changed - ' + cache_key - CacheIn.set( cache_key, ticket_create_attributes, { :expires_in => 2.minutes } ) - end - end - - # recent viewed - cache_key = @cache_key + '_recent_viewed' - if CacheIn.expired(cache_key) - recent_viewed = RecentView.list_fulldata( user, 10 ) - recent_viewed_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch recent_viewed - ' + cache_key - if recent_viewed != recent_viewed_cache - self.log 'notify', 'fetch recent_viewed changed - ' + cache_key - - recent_viewed_full = RecentView.list_fulldata( user, 10 ) - CacheIn.set( cache_key, recent_viewed, { :expires_in => 5.seconds } ) - CacheIn.set( cache_key + '_push', recent_viewed_full ) - end - end - - # activity steam - cache_key = @cache_key + '_activity_stream' - if CacheIn.expired(cache_key) - activity_stream = History.activity_stream( user, 20 ) - activity_stream_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch activity_stream - ' + cache_key - if activity_stream != activity_stream_cache - self.log 'notify', 'fetch activity_stream changed - ' + cache_key - - activity_stream_full = History.activity_stream_fulldata( user, 20 ) - CacheIn.set( cache_key, activity_stream, { :expires_in => 0.75.minutes } ) - CacheIn.set( cache_key + '_push', activity_stream_full ) - end - end - - # rss - cache_key = @cache_key + '_rss' - if CacheIn.expired(cache_key) - url = 'http://www.heise.de/newsticker/heise-atom.xml' - rss_items = Rss.fetch( url, 8 ) - rss_items_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.log 'notice', 'fetch rss - ' + cache_key - if rss_items != rss_items_cache - self.log 'notify', 'fetch rss changed - ' + cache_key - CacheIn.set( cache_key, rss_items, { :expires_in => 2.minutes } ) - CacheIn.set( cache_key + '_push', { - head: 'Heise ATOM', - items: rss_items, - }) - end - end - - # auto population of default collections - self.log 'notice', "---user - fetch push_collection data" - - # get available collections - cache_key = @cache_key + '_push_collections' - collections = CacheIn.get( cache_key ) - if !collections - collections = {} - push_collection = SessionHelper::push_collections(user) - push_collection.each { | key, value | - collections[ key ] = true - } - CacheIn.set( cache_key, collections, { :expires_in => 2.minutes } ) - end - - # check all collections to push - push_collection = {} - collections.each { | key, v | - cache_key = @cache_key + '_push_collections_' + key - if CacheIn.expired(cache_key) - if push_collection.empty? - push_collection = SessionHelper::push_collections(user) - end - push_collection_cache = CacheIn.get( cache_key, { :re_expire => true } ) - self.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 } - self.log 'notify', 'fetch push_collection changed - ' + cache_key - CacheIn.set( cache_key, push_collection[key], { :expires_in => 1.minutes } ) - end - end - } - - self.log 'notice', "---/user-" - sleep 1 - end - end - - def log( level, data ) - return if level == 'notice' - puts "#{Time.now}:user_id(#{ @user_id }) #{ data }" - end -end - - -class ClientState - def initialize( client_id ) - @client_id = client_id - @cache_key = '' - @data = {} - @pushed = {} - self.log 'notify', "---client start ws connection---" - self.fetch - self.log 'notify', "---client exiting ws connection---" - end - - def fetch - - loop_count = 0 - while true - - # get connection user - session_data = Sessions.get( @client_id ) - return if !session_data - return if !session_data[:user] - return if !session_data[:user][:id] - user = User.lookup( :id => session_data[:user][:id] ) - return if !user - - # set cache key - @cache_key = 'user_' + user.id.to_s - - loop_count += 1 - self.log 'notice', "---client - looking for data of user #{user.id}" - - # remember last run - CacheIn.set( 'last_run_' + user.id.to_s , true, { :expires_in => 20.seconds } ) - - # verify already pushed data - if !CacheIn.get( 'pushed_users' + @client_id.to_s ) - CacheIn.set( 'pushed_users' + @client_id.to_s , true, { :expires_in => 20.seconds } ) - if @pushed[:users] - users = {} - @pushed[:users].each {|user_id, user_o| - self.user( user_id, users ) - } - if !users.empty? - users.each {|user_id, user_data| - self.log 'notify', "push update of already pushed user id #{user_id}" - } - # send update to browser - self.send({ - :data => { - :collections => { - :User => users, - }, - }, - :event => [ 'loadCollection', 'ticket_overview_rebuild' ], - }); - end - end - end - - # verify already pushed data - if !CacheIn.get( 'pushed_tickets' + @client_id.to_s ) - CacheIn.set( 'pushed_tickets' + @client_id.to_s , true, { :expires_in => 20.seconds } ) - if @pushed[:tickets] - tickets = {} - users = {} - @pushed[:tickets].each {|ticket_id, ticket_data| - self.ticket( ticket_id, tickets, users ) - } - if !tickets.empty? - tickets.each {|id, ticket| - self.log 'notify', "push update of already pushed ticket id #{id}" - } - # send update to browser - self.send({ - :data => { - :collections => { - :Ticket => tickets, - :User => users, - }, - }, - :event => [ 'loadCollection', 'ticket_overview_rebuild' ], - }); - end - end - end - - # overview - cache_key = @cache_key + '_overview' - overview_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if overview_time && @data[:overview_time] != overview_time - @data[:overview_time] = overview_time - overview = CacheIn.get( cache_key, { :ignore_expire => true } ) - - self.log 'notify', "push overview for user #{user.id}" - - # send update to browser - self.send({ - :event => 'navupdate_ticket_overview', - :data => overview, - }) - end - - # overview_data - overviews = Ticket::Overviews.all( - :current_user => user, - ) - overviews.each { |overview| - cache_key = @cache_key + '_overview_data_' + overview.link - - overview_data_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if overview_data_time && @data[cache_key] != overview_data_time - @data[cache_key] = overview_data_time - overview_data = CacheIn.get( cache_key, { :ignore_expire => true } ) - self.log 'notify', "push overview_data #{overview.link} for user #{user.id}" - users = {} - tickets = {} - overview_data[:ticket_ids].each {|ticket_id| - self.ticket( ticket_id, tickets, users ) - } - - # get groups - group_ids = [] - Group.where( :active => true ).each { |group| - group_ids.push group.id - } - agents = {} - Ticket::ScreenOptions.agents.each { |user| - agents[ user.id ] = 1 - } - groups_users = {} - groups_users[''] = [] - group_ids.each {|group_id| - groups_users[ group_id ] = [] - Group.find(group_id).users.each {|user| - next if !agents[ user.id ] - groups_users[ group_id ].push user.id - if !users[user.id] - users[user.id] = User.user_data_full(user.id) - end - } - } - - # send update to browser - self.send({ - :data => { - :users => users, - :tickets => tickets, - }, - :event => [ 'loadAssets' ] - }) - self.send({ - :data => { - :overview => overview_data[:overview], - :ticket_ids => overview_data[:ticket_ids], - :tickets_count => overview_data[:tickets_count], - :bulk => { - :group_id__owner_id => groups_users, - :owner_id => [], - }, - }, - :event => [ 'ticket_overview_rebuild' ], - :collection => 'ticket_overview_' + overview.link.to_s, - }) - end - } - - # ticket_create_attributes - cache_key = @cache_key + '_ticket_create_attributes' - ticket_create_attributes_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if ticket_create_attributes_time && @data[:ticket_create_attributes_time] != ticket_create_attributes_time - @data[:ticket_create_attributes_time] = ticket_create_attributes_time - create_attributes = CacheIn.get( cache_key, { :ignore_expire => true } ) - users = {} - create_attributes[:owner_id].each {|user_id| - if !users[user_id] - users[user_id] = User.user_data_full(user_id) - end - } - data = { - :users => users, - :edit_form => create_attributes, - } - self.log 'notify', "push ticket_create_attributes for user #{user.id}" - - # send update to browser - self.send({ - :collection => 'ticket_create_attributes', - :data => data, - }) - end - - # recent viewed - cache_key = @cache_key + '_recent_viewed' - recent_viewed_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if recent_viewed_time && @data[:recent_viewed_time] != recent_viewed_time - @data[:recent_viewed_time] = recent_viewed_time - recent_viewed = CacheIn.get( cache_key, { :ignore_expire => true } ) - self.log 'notify', "push recent_viewed for user #{user.id}" - - # send update to browser - r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.send({ - :event => 'update_recent_viewed', - :data => r, - }) - end - - # activity stream - cache_key = @cache_key + '_activity_stream' - activity_stream_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if activity_stream_time && @data[:activity_stream_time] != activity_stream_time - @data[:activity_stream_time] = activity_stream_time - activity_stream = CacheIn.get( cache_key, { :ignore_expire => true } ) - self.log 'notify', "push activity_stream for user #{user.id}" - - # send update to browser - r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.send({ - :event => 'activity_stream_rebuild', - :collection => 'activity_stream', - :data => r, - }) - end - - # rss - cache_key = @cache_key + '_rss' - rss_items_time = CacheIn.get_time( cache_key, { :ignore_expire => true } ) - if rss_items_time && @data[:rss_time] != rss_items_time - @data[:rss_time] = rss_items_time - rss_items = CacheIn.get( cache_key, { :ignore_expire => true } ) - self.log 'notify', "push rss for user #{user.id}" - - # send update to browser - r = CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) - self.send({ - :event => 'rss_rebuild', - :collection => 'dashboard_rss', - :data => r, - }) - end - - # push_collections - cache_key = @cache_key + '_push_collections' - collections = CacheIn.get( cache_key ) || {} - collections.each { | key, v | - collection_cache_key = @cache_key + '_push_collections_' + key - collection_time = CacheIn.get_time( collection_cache_key, { :ignore_expire => true } ) - if collection_time && @data[ collection_cache_key + '_time' ] != collection_time - - @data[ collection_cache_key + '_time' ] = collection_time - push_collections = CacheIn.get( collection_cache_key, { :ignore_expire => true } ) - - self.log 'notify', "push push_collections #{key} for user #{user.id}" - - # send update to browser - data = {} - data['collections'] = {} - data['collections'][key] = push_collections - self.send({ - :event => 'resetCollection', - :data => data, - }) - - end - } - - self.log 'notice', "---/client-" - - # start faster in the beginnig - if loop_count < 20 - sleep 0.6 - else - sleep 1 - end - end - end - - # add ticket if needed - def ticket( ticket_id, tickets, users ) - if !@pushed[:tickets] - @pushed[:tickets] = {} - end - ticket = Ticket.lookup( :id => ticket_id ) - if @pushed[:tickets][ticket_id] != ticket['updated_at'] - @pushed[:tickets][ticket_id] = ticket['updated_at'] - tickets[ticket_id] = ticket - end - - # add users if needed - self.user( ticket['owner_id'], users ) - self.user( ticket['customer_id'], users ) - self.user( ticket['created_by_id'], users ) - if ticket['updated_by_id'] - self.user( ticket['updated_by_id'], users ) - end - end - - # add user if needed - def user( user_id, users ) - if !@pushed[:users] - @pushed[:users] = {} - end - - # get user - user = User.user_data_full( user_id ) - - # user is already on client and not changed - return if @pushed[:users][ user_id ] == user['updated_at'] - @pushed[:users][user_id] = user['updated_at'] - - # user not on client or different - self.log 'notice', 'push user ... ' + user['login'] - users[ user_id ] = user - end - - # send update to browser - def send( data ) - Sessions.send( @client_id, data ) - end - - def log( level, data ) - return if level == 'notice' - puts "#{Time.now}:client(#{ @client_id }) #{ data }" - end -end +end \ No newline at end of file diff --git a/lib/sessions/backend.rb b/lib/sessions/backend.rb new file mode 100644 index 000000000..2996b58a6 --- /dev/null +++ b/lib/sessions/backend.rb @@ -0,0 +1,2 @@ +module Sessions::Backend +end diff --git a/lib/sessions/backend/activity_stream.rb b/lib/sessions/backend/activity_stream.rb new file mode 100644 index 000000000..2164f8057 --- /dev/null +++ b/lib/sessions/backend/activity_stream.rb @@ -0,0 +1,39 @@ +module Sessions::Backend::ActivityStream + @@last_change = {} + + def self.worker( user, worker ) + cache_key = 'user_' + user.id.to_s + '_activity_stream' + if Sessions::CacheIn.expired(cache_key) + activity_stream = History.activity_stream( user, 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 = History.activity_stream_fulldata( user, 20 ) + Sessions::CacheIn.set( cache_key, activity_stream, { :expires_in => 0.75.minutes } ) + Sessions::CacheIn.set( cache_key + '_push', activity_stream_full ) + end + end + end + + def self.push( user, client ) + cache_key = 'user_' + user.id.to_s + '_activity_stream' + + activity_stream_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if activity_stream_time && @@last_change[ user.id ] != activity_stream_time + @@last_change[ user.id ] = activity_stream_time + activity_stream = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + client.log 'notify', "push activity_stream for user #{user.id}" + + # send update to browser + r = Sessions::CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) + client.send({ + :event => 'activity_stream_rebuild', + :collection => 'activity_stream', + :data => r, + }) + end + end + +end \ No newline at end of file diff --git a/lib/sessions/backend/collections.rb b/lib/sessions/backend/collections.rb new file mode 100644 index 000000000..5416c54b6 --- /dev/null +++ b/lib/sessions/backend/collections.rb @@ -0,0 +1,70 @@ +module Sessions::Backend::Collections + @@last_change = {} + + 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 + + # check all collections to push + push_collection = {} + collections.each { | key, v | + cache_key = 'user_' + user.id.to_s + '_push_collections_' + key + 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 } + worker.log 'notify', 'fetch push_collection changed - ' + cache_key + Sessions::CacheIn.set( cache_key, push_collection[key], { :expires_in => 1.minutes } ) + end + end + } + + end + + def self.push( user, client ) + + cache_key = 'user_' + user.id.to_s + '_push_collections' + if !@@last_change[ user.id ] + @@last_change[ user.id ] = {} + end + + collections = Sessions::CacheIn.get( cache_key ) || {} + collections.each { | key, v | + collection_cache_key = 'user_' + user.id.to_s + '_push_collections_' + key + collection_time = Sessions::CacheIn.get_time( collection_cache_key, { :ignore_expire => true } ) + if collection_time && @@last_change[ user.id ][ key ] != collection_time + + @@last_change[ user.id ][ 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['collections'] = {} + data['collections'][key] = push_collections + client.send({ + :event => 'resetCollection', + :data => data, + }) + + end + } + end + +end diff --git a/lib/sessions/backend/recent_viewed.rb b/lib/sessions/backend/recent_viewed.rb new file mode 100644 index 000000000..24c02d60a --- /dev/null +++ b/lib/sessions/backend/recent_viewed.rb @@ -0,0 +1,38 @@ +module Sessions::Backend::RecentViewed + @@last_change = {} + + def self.worker( user, worker ) + cache_key = 'user_' + user.id.to_s + '_recent_viewed' + if Sessions::CacheIn.expired(cache_key) + recent_viewed = RecentView.list_fulldata( user, 10 ) + recent_viewed_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } ) + worker.log 'notice', 'fetch recent_viewed - ' + cache_key + if recent_viewed != recent_viewed_cache + worker.log 'notify', 'fetch recent_viewed changed - ' + cache_key + + recent_viewed_full = RecentView.list_fulldata( user, 10 ) + Sessions::CacheIn.set( cache_key, recent_viewed, { :expires_in => 5.seconds } ) + Sessions::CacheIn.set( cache_key + '_push', recent_viewed_full ) + end + end + + end + + def self.push( user, client ) + cache_key = 'user_' + user.id.to_s + '_recent_viewed' + recent_viewed_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if recent_viewed_time && @@last_change[ user.id ] != recent_viewed_time + @@last_change[ user.id ] = recent_viewed_time + recent_viewed = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + client.log 'notify', "push recent_viewed for user #{user.id}" + + # send update to browser + r = Sessions::CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) + client.send({ + :event => 'update_recent_viewed', + :data => r, + }) + end + end + +end diff --git a/lib/sessions/backend/rss.rb b/lib/sessions/backend/rss.rb new file mode 100644 index 000000000..e223b93cb --- /dev/null +++ b/lib/sessions/backend/rss.rb @@ -0,0 +1,41 @@ +module Sessions::Backend::Rss + @@last_change = {} + + def self.worker( user, worker ) + cache_key = 'user_' + user.id.to_s + '_rss' + if Sessions::CacheIn.expired(cache_key) + url = 'http://www.heise.de/newsticker/heise-atom.xml' + rss_items = Rss.fetch( url, 8 ) + rss_items_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } ) + worker.log 'notice', 'fetch rss - ' + cache_key + if rss_items != rss_items_cache + worker.log 'notify', 'fetch rss changed - ' + cache_key + Sessions::CacheIn.set( cache_key, rss_items, { :expires_in => 2.minutes } ) + Sessions::CacheIn.set( cache_key + '_push', { + head: 'Heise ATOM', + items: rss_items, + }) + end + end + end + + def self.push( user, client ) + cache_key = 'user_' + user.id.to_s + '_rss' + + rss_items_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if rss_items_time && @@last_change[ user.id ] != rss_items_time + @@last_change[ user.id ] = rss_items_time + rss_items = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + client.log 'notify', "push rss for user #{user.id}" + + # send update to browser + r = Sessions::CacheIn.get( cache_key + '_push', { :ignore_expire => true } ) + client.send({ + :event => 'rss_rebuild', + :collection => 'dashboard_rss', + :data => r, + }) + end + end + +end diff --git a/lib/sessions/backend/ticket_create.rb b/lib/sessions/backend/ticket_create.rb new file mode 100644 index 000000000..a03f43d7b --- /dev/null +++ b/lib/sessions/backend/ticket_create.rb @@ -0,0 +1,48 @@ +module Sessions::Backend::TicketCreate + @@last_change = {} + + def self.worker( user, worker ) + cache_key = 'user_' + user.id.to_s + '_ticket_create_attributes' + + if Sessions::CacheIn.expired(cache_key) + ticket_create_attributes = Ticket::ScreenOptions.attributes_to_change( + :current_user_id => user.id, + ) + ticket_create_attributes_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } ) + worker.log 'notice', 'fetch ticket_create_attributes - ' + cache_key + if ticket_create_attributes != ticket_create_attributes_cache + worker.log 'notify', 'fetch ticket_create_attributes changed - ' + cache_key + Sessions::CacheIn.set( cache_key, ticket_create_attributes, { :expires_in => 2.minutes } ) + end + end + + end + + def self.push( user, client ) + cache_key = 'user_' + user.id.to_s + '_ticket_create_attributes' + + ticket_create_attributes_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if ticket_create_attributes_time && @@last_change[ user.id ] != ticket_create_attributes_time + @@last_change[ user.id ] = ticket_create_attributes_time + create_attributes = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + users = {} + create_attributes[:owner_id].each {|user_id| + if !users[user_id] + users[user_id] = User.user_data_full(user_id) + end + } + data = { + :users => users, + :edit_form => create_attributes, + } + client.log 'notify', "push ticket_create_attributes for user #{user.id}" + + # send update to browser + client.send({ + :collection => 'ticket_create_attributes', + :data => data, + }) + end + end + +end diff --git a/lib/sessions/backend/ticket_overview_index.rb b/lib/sessions/backend/ticket_overview_index.rb new file mode 100644 index 000000000..5e759e301 --- /dev/null +++ b/lib/sessions/backend/ticket_overview_index.rb @@ -0,0 +1,39 @@ +module Sessions::Backend::TicketOverviewIndex + @@last_change = {} + + def self.worker( user, worker ) + cache_key = 'user_' + user.id.to_s + '_overview' + if Sessions::CacheIn.expired(cache_key) + overview = Ticket::Overviews.list( + :current_user => user, + ) + overview_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } ) + worker.log 'notice', 'fetch overview - ' + cache_key + if overview != overview_cache + worker.log 'notify', 'fetch overview changed - ' + cache_key +# puts overview.inspect +# puts '------' +# puts overview_cache.inspect + Sessions::CacheIn.set( cache_key, overview, { :expires_in => 4.seconds } ) + end + end + end + + def self.push( user, client ) + cache_key = 'user_' + user.id.to_s + '_overview' + overview_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if overview_time && @@last_change[ user.id ] != overview_time + @@last_change[ user.id ] = overview_time + overview = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + + client.log 'notify', "push overview for user #{user.id}" + + # send update to browser + client.send({ + :event => 'navupdate_ticket_overview', + :data => overview, + }) + end + end + +end diff --git a/lib/sessions/backend/ticket_overview_list.rb b/lib/sessions/backend/ticket_overview_list.rb new file mode 100644 index 000000000..824af2081 --- /dev/null +++ b/lib/sessions/backend/ticket_overview_list.rb @@ -0,0 +1,95 @@ +module Sessions::Backend::TicketOverviewList + @@last_change = {} + + def self.worker( user, worker ) + overviews = Ticket::Overviews.all( + :current_user => user, + ) + overviews.each { |overview| + cache_key = 'user_' + user.id.to_s + '_overview_data_' + overview.link + if Sessions::CacheIn.expired(cache_key) + overview_data = Ticket::Overviews.list( + :view => overview.link, + :current_user => user, + :array => true, + ) + overview_data_cache = Sessions::CacheIn.get( cache_key, { :re_expire => true } ) + worker.log 'notice', 'fetch overview_data - ' + cache_key + if overview_data != overview_data_cache + worker.log 'notify', 'fetch overview_data changed - ' + cache_key + Sessions::CacheIn.set( cache_key, overview_data, { :expires_in => 5.seconds } ) + end + end + } + end + + def self.push( user, client ) + overviews = Ticket::Overviews.all( + :current_user => user, + ) + overviews.each { |overview| + cache_key = 'user_' + user.id.to_s + '_overview_data_' + overview.link + + if !@@last_change[ user.id ] + @@last_change[ user.id ] = {} + end + + overview_data_time = Sessions::CacheIn.get_time( cache_key, { :ignore_expire => true } ) + if overview_data_time && @@last_change[ user.id ][overview.link] != overview_data_time + @@last_change[ user.id ][overview.link] = overview_data_time + overview_data = Sessions::CacheIn.get( cache_key, { :ignore_expire => true } ) + client.log 'notify', "push overview_data #{overview.link} for user #{user.id}" + users = {} + tickets = {} + overview_data[:ticket_ids].each {|ticket_id| + client.ticket( ticket_id, tickets, users ) + } + + # get groups + group_ids = [] + Group.where( :active => true ).each { |group| + group_ids.push group.id + } + agents = {} + Ticket::ScreenOptions.agents.each { |user| + agents[ user.id ] = 1 + } + groups_users = {} + groups_users[''] = [] + group_ids.each {|group_id| + groups_users[ group_id ] = [] + Group.find(group_id).users.each {|user| + next if !agents[ user.id ] + groups_users[ group_id ].push user.id + if !users[user.id] + users[user.id] = User.user_data_full(user.id) + end + } + } + + # send update to browser + client.send({ + :data => { + User.to_online_model.to_sym => users, + Ticket.to_online_model.to_sym => tickets, + }, + :event => [ 'loadAssets' ] + }) + client.send({ + :data => { + :overview => overview_data[:overview], + :ticket_ids => overview_data[:ticket_ids], + :tickets_count => overview_data[:tickets_count], + :bulk => { + :group_id__owner_id => groups_users, + :owner_id => [], + }, + }, + :event => [ 'ticket_overview_rebuild' ], + :collection => 'ticket_overview_' + overview.link.to_s, + }) + end + } + end + +end diff --git a/lib/sessions/cache_in.rb b/lib/sessions/cache_in.rb new file mode 100644 index 000000000..f583d7dfd --- /dev/null +++ b/lib/sessions/cache_in.rb @@ -0,0 +1,56 @@ +module Sessions::CacheIn + @@data = {} + @@data_time = {} + @@expires_in = {} + @@expires_in_ttl = {} + + def self.set( key, value, params = {} ) +# puts 'CacheIn.set:' + key + '-' + value.inspect + if params[:expires_in] + @@expires_in[key] = Time.now + params[:expires_in] + @@expires_in_ttl[key] = params[:expires_in] + end + @@data[ key ] = value + @@data_time[ key ] = Time.now + end + + def self.expired( key, params = {} ) + + # expire if value never was set + return true if !@@data.include? key + + # ignore_expire + return false if params[:ignore_expire] + + # set re_expire + if params[:re_expire] + if @@expires_in[key] + @@expires_in[key] = Time.now + @@expires_in_ttl[key] + end + return false + end + + # check if expired + if @@expires_in[key] + return true if @@expires_in[key] < Time.now + return false + end + + # return false if key was set without expires_in + return false + end + + def self.get_time( key, params = {} ) + data = self.get( key, params ) + if data + return @@data_time[key] + end + return nil + end + + def self.get( key, params = {} ) +# puts 'CacheIn.get:' + key + '-' + @@data[ key ].inspect + return if self.expired( key, params ) + @@data[ key ] + end +end diff --git a/lib/sessions/client.rb b/lib/sessions/client.rb new file mode 100644 index 000000000..f5b53b00c --- /dev/null +++ b/lib/sessions/client.rb @@ -0,0 +1,165 @@ +class Sessions::Client + def initialize( client_id ) + @client_id = client_id + @cache_key = '' + @data = {} + @pushed = {} + self.log 'notify', "---client start ws connection---" + self.fetch + self.log 'notify', "---client exiting ws connection---" + end + + def fetch + + loop_count = 0 + while true + + # get connection user + session_data = Sessions.get( @client_id ) + return if !session_data + return if !session_data[:user] + return if !session_data[:user][:id] + user = User.lookup( :id => session_data[:user][:id] ) + return if !user + + # set cache key + @cache_key = 'user_' + user.id.to_s + + loop_count += 1 + self.log 'notice', "---client - looking for data of user #{user.id}" + + # remember last run + Sessions::CacheIn.set( 'last_run_' + user.id.to_s , true, { :expires_in => 20.seconds } ) + + # verify already pushed data + if !Sessions::CacheIn.get( 'pushed_users' + @client_id.to_s ) + Sessions::CacheIn.set( 'pushed_users' + @client_id.to_s , true, { :expires_in => 20.seconds } ) + if @pushed[:users] + users = {} + @pushed[:users].each {|user_id, user_o| + self.user( user_id, users ) + } + if !users.empty? + users.each {|user_id, user_data| + self.log 'notify', "push update of already pushed user id #{user_id}" + } + # send update to browser + self.send({ + :data => { + :collections => { + User.to_online_model.to_sym => users, + }, + }, + :event => [ 'loadCollection', 'ticket_overview_rebuild' ], + }); + end + end + end + + # verify already pushed data + if !Sessions::CacheIn.get( 'pushed_tickets' + @client_id.to_s ) + Sessions::CacheIn.set( 'pushed_tickets' + @client_id.to_s , true, { :expires_in => 20.seconds } ) + if @pushed[:tickets] + tickets = {} + users = {} + @pushed[:tickets].each {|ticket_id, ticket_data| + self.ticket( ticket_id, tickets, users ) + } + if !tickets.empty? + tickets.each {|id, ticket| + self.log 'notify', "push update of already pushed ticket id #{id}" + } + # send update to browser + self.send({ + :data => { + :collections => { + Ticket.to_online_model.to_sym => tickets, + User.to_online_model.to_sym => users, + }, + }, + :event => [ 'loadCollection', 'ticket_overview_rebuild' ], + }); + end + end + end + + # overview + Sessions::Backend::TicketOverviewIndex.push( user, self ) + + # overview_data + Sessions::Backend::TicketOverviewList.push( user, self ) + + # ticket_create_attributes + Sessions::Backend::TicketCreate.push( user, self ) + + # recent viewed + Sessions::Backend::RecentViewed.push( user, self ) + + # activity stream + Sessions::Backend::ActivityStream.push( user, self ) + + # rss + Sessions::Backend::Rss.push( user, self ) + + # push_collections + Sessions::Backend::Collections.push( user, self ) + + self.log 'notice', "---/client-" + + # start faster in the beginnig + if loop_count < 20 + sleep 0.6 + else + sleep 1 + end + end + end + + # add ticket if needed + def ticket( ticket_id, tickets, users ) + if !@pushed[:tickets] + @pushed[:tickets] = {} + end + ticket = Ticket.lookup( :id => ticket_id ) + if @pushed[:tickets][ticket_id] != ticket['updated_at'] + @pushed[:tickets][ticket_id] = ticket['updated_at'] + tickets[ticket_id] = ticket + end + + # add users if needed + self.user( ticket['owner_id'], users ) + self.user( ticket['customer_id'], users ) + self.user( ticket['created_by_id'], users ) + if ticket['updated_by_id'] + self.user( ticket['updated_by_id'], users ) + end + end + + # add user if needed + def user( user_id, users ) + if !@pushed[:users] + @pushed[:users] = {} + end + + # get user + user = User.user_data_full( user_id ) + + # user is already on client and not changed + return if @pushed[:users][ user_id ] == user['updated_at'] + @pushed[:users][user_id] = user['updated_at'] + + # user not on client or different + self.log 'notice', 'push user ... ' + user['login'] + users[ user_id ] = user + end + + # send update to browser + def send( data ) + Sessions.send( @client_id, data ) + end + + def log( level, data ) + return if level == 'notice' + puts "#{Time.now}:client(#{ @client_id }) #{ data }" + end +end diff --git a/lib/sessions/worker.rb b/lib/sessions/worker.rb new file mode 100644 index 000000000..9eea1840f --- /dev/null +++ b/lib/sessions/worker.rb @@ -0,0 +1,58 @@ +class Sessions::Worker + def initialize( user_id ) + @user_id = user_id + @data = {} + @cache_key = 'user_' + user_id.to_s + self.log 'notify', "---user started user state" + + Sessions::CacheIn.set( 'last_run_' + user_id.to_s , true, { :expires_in => 20.seconds } ) + + user = User.find( @user_id ) + return if !user + + self.fetch( user ) + end + + def fetch(user) + + while true + + # check if user is still with min one open connection + if !Sessions::CacheIn.get( 'last_run_' + user.id.to_s ) + self.log 'notify', "---user - closeing thread - no open user connection" + return + end + + self.log 'notice', "---user - fetch user data" + # overview + Sessions::Backend::TicketOverviewIndex.worker( user, self ) + + # overview lists + Sessions::Backend::TicketOverviewList.worker( user, self ) + + # create_attributes + Sessions::Backend::TicketCreate.worker( user, self ) + + # recent viewed + Sessions::Backend::RecentViewed.worker( user, self ) + + # activity steam + Sessions::Backend::ActivityStream.worker( user, self ) + + # rss + Sessions::Backend::Rss.worker( user, self ) + + # auto population of default collections + Sessions::Backend::Collections.worker( user, self ) + + self.log 'notice', "---/user-" + sleep 1 + end + end + + def log( level, data ) + return if level == 'notice' + puts "#{Time.now}:user_id(#{ @user_id }) #{ data }" + end +end +