<commit_before>#!/usr/bin/env ruby
# encoding: utf-8
#--
#
# State Based Session Management
# Copyright (C) 2004 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Zürich, Switzerland
# <EMAIL>
#
# SessionStore -- sbsm -- <EMAIL>
#  2016: ported this code from the old DrbServer
#++

require 'delegate'
require 'sbsm/session'
require 'sbsm/user'
require 'thread'
require 'digest/md5'
require 'sbsm/logger'
require 'sbsm/validator'
require 'sbsm/session_store'

module SBSM
  #
  # SessionStore manages session, which are kept in memory
  # Sessions are limited and expire after some time
  # The maximal amount of concurrent session is given via CAP_MAX_THRESHOLD
  #
  class SessionStore
    CLEANING_INTERVAL = 30
    CAP_MAX_THRESHOLD = 120
    MAX_SESSIONS = 100
    RUN_CLEANER = true
    SESSION = Session
    UNKNOWN_USER = UnknownUser
    VALIDATOR = nil
    attr_reader :cleaner, :updater, :persistence_layer
    @@mutex = Mutex.new
    @@sessions = {}
    def initialize(app:,
                   persistence_layer: nil,
                   trans_handler: nil,
                   session_class: nil,
                   validator: nil,
                   cookie_name: nil,
                   unknown_user: UNKNOWN_USER.new,
                   multi_threaded: nil)
      fail "You must specify an app!" unless app
      @@sessions = {}
      @cleaner = run_cleaner if(self.class.const_get(:RUN_CLEANER))
      @app = app
      @system = persistence_layer
      @persistence_layer = persistence_layer
      @cookie_name = cookie_name
      @trans_handler = trans_handler
      @trans_handler ||= TransHandler.instance
      @session_class = session_class
      @session_class ||= SBSM::Session
      @unknown_user = unknown_user.is_a?(Class) ? unknown_user.new : unknown_user
      @unknown_user ||= UnknownUser.new
      @validator = validator
    end
    def cap_max_sessions(now = Time.now)
        if(@@sessions.size > self::class::CAP_MAX_THRESHOLD)
          SBSM.info "too many sessions! Keeping only #{self::class::MAX_SESSIONS}"
          sess = nil
          @@sessions.values.sort[0...(-self::class::MAX_SESSIONS)].each { |sess|
            sess.__checkout
            @@sessions.delete(sess.key)
          }
          if(sess)
            age = sess.age(now)
            SBSM.info sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
          end
        end
      seconds = (Time.now.to_i - now.to_i)
      SBSM.warn sprintf("cap_max_sessions to #{self::class::CAP_MAX_THRESHOLD}. took %d seconds", seconds)
    end
    def clean
      now = Time.now
      old_size = @@sessions.size
      @@sessions.delete_if do |key, s|
        begin
          if s.respond_to?(:expired?)
            if s.expired?(now)
              s.__checkout
              true
            else
              s.cap_max_states
              false
            end
          else
            true
          end
        rescue
          true
        end
      end
      seconds = (Time.now.to_i - now.to_i)
      SBSM.warn sprintf("Cleaned #{old_size - @@sessions.size} sessions. Took %d seconds", seconds)
    end
    def SessionStore.sessions
      @@sessions
    end

    def SessionStore.clear
      @@mutex.synchronize do
        @@sessions.each_value { |sess| sess.__checkout }
        @@sessions.clear
      end
    end
    def delete_session(key)
      if(sess = @@sessions.delete(key))
        sess.__checkout
      end
    end
    def reset
      @@mutex.synchronize {
        @@sessions.clear
      }
    end
    def run_cleaner
      # puts "running cleaner thread"
      Thread.new do
        Thread.current.abort_on_exception = true
        #Thread.current.priority = 1<commit_msg>Silence run_cleaner<commit_after>#!/usr/bin/env ruby
# encoding: utf-8
#--
#
# State Based Session Management
# Copyright (C) 2004 <NAME>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# ywesee - intellectual capital connected, Winterthurerstrasse 52, CH-8006 Zürich, Switzerland
# <EMAIL>
#
# SessionStore -- sbsm -- <EMAIL>
#  2016: ported this code from the old DrbServer
#++

require 'delegate'
require 'sbsm/session'
require 'sbsm/user'
require 'thread'
require 'digest/md5'
require 'sbsm/logger'
require 'sbsm/validator'
require 'sbsm/session_store'

module SBSM
  #
  # SessionStore manages session, which are kept in memory
  # Sessions are limited and expire after some time
  # The maximal amount of concurrent session is given via CAP_MAX_THRESHOLD
  #
  class SessionStore
    CLEANING_INTERVAL = 30
    CAP_MAX_THRESHOLD = 120
    MAX_SESSIONS = 100
    RUN_CLEANER = true
    SESSION = Session
    UNKNOWN_USER = UnknownUser
    VALIDATOR = nil
    attr_reader :cleaner, :updater, :persistence_layer
    @@mutex = Mutex.new
    @@sessions = {}
    def initialize(app:,
                   persistence_layer: nil,
                   trans_handler: nil,
                   session_class: nil,
                   validator: nil,
                   cookie_name: nil,
                   unknown_user: UNKNOWN_USER.new,
                   multi_threaded: nil)
      fail "You must specify an app!" unless app
      @@sessions = {}
      @cleaner = run_cleaner if(self.class.const_get(:RUN_CLEANER))
      @app = app
      @system = persistence_layer
      @persistence_layer = persistence_layer
      @cookie_name = cookie_name
      @trans_handler = trans_handler
      @trans_handler ||= TransHandler.instance
      @session_class = session_class
      @session_class ||= SBSM::Session
      @unknown_user = unknown_user.is_a?(Class) ? unknown_user.new : unknown_user
      @unknown_user ||= UnknownUser.new
      @validator = validator
    end
    def cap_max_sessions(now = Time.now)
        if(@@sessions.size > self::class::CAP_MAX_THRESHOLD)
          SBSM.info "too many sessions! Keeping only #{self::class::MAX_SESSIONS}"
          sess = nil
          @@sessions.values.sort[0...(-self::class::MAX_SESSIONS)].each { |sess|
            sess.__checkout
            @@sessions.delete(sess.key)
          }
          if(sess)
            age = sess.age(now)
            SBSM.info sprintf("deleted all sessions that had not been accessed for more than %im %is", age / 60, age % 60)
          end
        end
      seconds = (Time.now.to_i - now.to_i)
      SBSM.warn sprintf("cap_max_sessions to #{self::class::CAP_MAX_THRESHOLD}. took %d seconds", seconds)
    end
    def clean
      now = Time.now
      old_size = @@sessions.size
      @@sessions.delete_if do |key, s|
        begin
          if s.respond_to?(:expired?)
            if s.expired?(now)
              s.__checkout
              true
            else
              s.cap_max_states
              false
            end
          else
            true
          end
        rescue
          true
        end
      end
      seconds = (Time.now.to_i - now.to_i)
      # SBSM.warn sprintf("Cleaned #{old_size - @@sessions.size} sessions. Took %d seconds", seconds)
    end
    def SessionStore.sessions
      @@sessions
    end

    def SessionStore.clear
      @@mutex.synchronize do
        @@sessions.each_value { |sess| sess.__checkout }
        @@sessions.clear
      end
    end
    def delete_session(key)
      if(sess = @@sessions.delete(key))
        sess.__checkout
      end
    end
    def reset
      @@mutex.synchronize {
        @@sessions.clear
      }
    end
    def run_cleaner
      # puts "running cleaner thread"
      Thread.new do
        Thread.current.abort_on_exception = true
        #Thread.current.priority = 1
{'fraction_non_alphanumeric': 0.08667111704494881, 'fraction_numerical': 0.010235870048954161, 'mean_word_length': 2.3354359925788497, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2611783', 'n_tokens_mistral': 2805, 'n_tokens_neox': 2674, 'n_words': 802}