<commit_before>class ServicesController < ApplicationController
  include ActionController::Live

  before_action :set_service, only: [:show, :edit, :update, :destroy]

  # GET /services
  # GET /services.json
  def index
    tries ||= 3
    @services = Service.all
    @plex_services = PlexService.all
    @weathers = Weather.all
  rescue ActiveRecord::StatementInvalid => e
    logger.error "There was an error interacting with the database. The error was: #{e}"
    sleep(0.25)
    retry unless (tries -= 1).zero?
  end


  # How to do SSE properly:
  # https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb#L23

  def notifications
    response.headers['Content-Type'] = 'text/event-stream'
    sse = SSE.new(response.stream, retry: 2000)
    begin
      loop do
        events = Array.new
        @plex_services = PlexService.all
        @services = Service.all
        # @weathers = Weather.all

        if @plex_services.empty? && @services.empty?
          logger.debug 'There were no PlexServices or Generic Services, sleeping for 10s.'
          sleep(10)
        end

        @plex_services.try(:each) do |plex_service|
          plex_service.update_plex_data
          all_active_sessions = []
          plex_service.plex_sessions.try(:each) do |plex_session|
            all_active_sessions << {session_id: plex_session.id,
                                    html: render_to_string(partial: 'plex_services/now_playing',
                                                           formats: [:html],
                                                           locals: {plex_session: plex_session,
                                                                    active: ''}),
                                    progress: plex_session.get_percent_done,
                                    active_sessions: PlexSession.all.ids}

          end
          if all_active_sessions.length > 0
            all_active_sessions.each do |active_session|
              events << {data: active_session, event: 'plex_now_playing'}
            end
          else
            events << {data: [], event: 'plex_now_playing'}
          end
        end

        @services.try(:each) do |service|
          unless service.ping_for_status_change.nil?
            events << {data: {id: service.id, html: render_to_string(partial: 'service', formats: [:html], locals: {service: service})}.to_json, event: 'online_status'}
          end
        end

        # @weathers.try(:each) do |weather|
        #   weather.get_weather
        #   events << {data: weather, event: 'weather'}
        # end

        events.each do |e|
          sse.write(e[:data], event: e[:event])
        end
        sleep 2
      end
    rescue IOError
      logger.warn 'Stream closed: IO Error'
    rescue ClientDisconnected
      logger.warn 'Stream closed: Client Disconnect'
        # rescue StandardError => e<commit_msg>Added mechanism to sync up clients who load pages between checks or if they miss an event from the stream<commit_after>class ServicesController < ApplicationController
  include ActionController::Live

  before_action :set_service, only: [:show, :edit, :update, :destroy]

  # GET /services
  # GET /services.json
  def index
    tries ||= 3
    @services = Service.all
    @plex_services = PlexService.all
    @weathers = Weather.all
  rescue ActiveRecord::StatementInvalid => e
    logger.error "There was an error interacting with the database. The error was: #{e}"
    sleep(0.25)
    retry unless (tries -= 1).zero?
  end


  # How to do SSE properly:
  # https://github.com/rails/rails/blob/6061c540ac7880233a6e32de85cec72c20ed8778/actionpack/lib/action_controller/metal/live.rb#L23

  def notifications
    response.headers['Content-Type'] = 'text/event-stream'
    sse = SSE.new(response.stream, retry: 2000)
    i = 0
    begin
      loop do
        i+= 1
        events = Array.new
        @plex_services = PlexService.all
        @services = Service.all
        # @weathers = Weather.all

        if @plex_services.empty? && @services.empty?
          logger.debug 'There were no PlexServices or Generic Services, sleeping for 10s.'
          sleep(10)
        end

        @plex_services.try(:each) do |plex_service|
          plex_service.update_plex_data
          all_active_sessions = []
          plex_service.plex_sessions.try(:each) do |plex_session|
            all_active_sessions << {session_id: plex_session.id,
                                    html: render_to_string(partial: 'plex_services/now_playing',
                                                           formats: [:html],
                                                           locals: {plex_session: plex_session,
                                                                    active: ''}),
                                    progress: plex_session.get_percent_done,
                                    active_sessions: PlexSession.all.ids}

          end
          if all_active_sessions.length > 0
            all_active_sessions.each do |active_session|
              events << {data: active_session, event: 'plex_now_playing'}
            end
          else
            events << {data: [], event: 'plex_now_playing'}
          end
        end

        @services.try(:each) do |service|
          if i % 10 == 0
            logger.debug('Looped 10 times, sending all service statuses.')
            service.ping
            events << {data: {id: service.id, html: render_to_string(partial: 'service', formats: [:html], locals: {service: service})}.to_json, event: 'online_status'}
          else
            unless service.ping_for_status_change.nil?
              events << {data: {id: service.id, html: render_to_string(partial: 'service', formats: [:html], locals: {service: service})}.to_json, event: 'online_status'}
            end
          end
        end

        # @weathers.try(:each) do |weather|
        #   weather.get_weather
        #   events << {data: weather, event: 'weather'}
        # end

        events.each do |e|
          sse.write(e[:data], event: e[:event])
        end
        sleep 2
      end
    rescue IOError
      logger.warn 'Stream closed: IO Error'
    rescue ClientDisconnected
      logger.warn 'Stream closed: Client Disconnect'
        # rescue StandardError => e
{'fraction_non_alphanumeric': 0.0962474485790548, 'fraction_numerical': 0.014915999371957922, 'mean_word_length': 1.9046967624259006, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 18, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2541573', 'n_tokens_mistral': 1836, 'n_tokens_neox': 1722, 'n_words': 432}