Commit 82e952a8 authored by João Cunha's avatar João Cunha

Move file one folder level up to avoid namespace conflict

Clusters::Cluster::KnativeServicesFinder becomes
Clusters::KnativeServicesFinder

This is to avoid loading race condition between:

```
module Clusters
  class Cluster < ApplicationRecord
```

and

```
module Clusters
  class Cluster
```
parent a2aa160c
# frozen_string_literal: true
module Clusters
class Cluster
class KnativeServicesFinder
include ReactiveCaching
include Gitlab::Utils::StrongMemoize
KNATIVE_STATES = {
'checking' => 'checking',
'installed' => 'installed',
'not_found' => 'not_found'
}.freeze
self.reactive_cache_key = ->(finder) { finder.model_name }
self.reactive_cache_worker_finder = ->(_id, *cache_args) { from_cache(*cache_args) }
attr_reader :cluster, :project
def initialize(cluster, project)
@cluster = cluster
@project = project
end
def with_reactive_cache_memoized(*cache_args, &block)
strong_memoize(:reactive_cache) do
with_reactive_cache(*cache_args, &block)
end
end
def clear_cache!
clear_reactive_cache!(*cache_args)
end
def self.from_cache(cluster_id, project_id)
cluster = Clusters::Cluster.find(cluster_id)
project = ::Project.find(project_id)
new(cluster, project)
end
def calculate_reactive_cache(*)
# read_services calls knative_client.discover implicitily. If we stop
# detecting services but still want to detect knative, we'll need to
# explicitily call: knative_client.discover
#
# We didn't create it separately to avoid 2 cluster requests.
ksvc = read_services
pods = knative_client.discovered ? read_pods : []
{ services: ksvc, pods: pods, knative_detected: knative_client.discovered }
end
def services
return [] unless search_namespace
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
cached_data.to_h.fetch(:services, [])
end
def cache_args
[cluster.id, project.id]
end
def service_pod_details(service)
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
cached_data.to_h.fetch(:pods, []).select do |pod|
filter_pods(pod, service)
end
end
def knative_detected
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
knative_state = cached_data.to_h[:knative_detected]
return KNATIVE_STATES['checking'] if knative_state.nil?
return KNATIVE_STATES['installed'] if knative_state
KNATIVE_STATES['uninstalled']
end
def model_name
self.class.name.underscore.tr('/', '_')
end
private
def search_namespace
@search_namespace ||= cluster.kubernetes_namespace_for(project)
end
def knative_client
cluster.kubeclient.knative_client
end
def filter_pods(pod, service)
pod["metadata"]["labels"]["serving.knative.dev/service"] == service
end
def read_services
knative_client.get_services(namespace: search_namespace).as_json
rescue Kubeclient::ResourceNotFoundError
[]
end
def read_pods
cluster.kubeclient.core_client.get_pods(namespace: search_namespace).as_json
end
def id
nil
end
end
end
end
# frozen_string_literal: true
module Clusters
class KnativeServicesFinder
include ReactiveCaching
include Gitlab::Utils::StrongMemoize
KNATIVE_STATES = {
'checking' => 'checking',
'installed' => 'installed',
'not_found' => 'not_found'
}.freeze
self.reactive_cache_key = ->(finder) { finder.model_name }
self.reactive_cache_worker_finder = ->(_id, *cache_args) { from_cache(*cache_args) }
attr_reader :cluster, :project
def initialize(cluster, project)
@cluster = cluster
@project = project
end
def with_reactive_cache_memoized(*cache_args, &block)
strong_memoize(:reactive_cache) do
with_reactive_cache(*cache_args, &block)
end
end
def clear_cache!
clear_reactive_cache!(*cache_args)
end
def self.from_cache(cluster_id, project_id)
cluster = Clusters::Cluster.find(cluster_id)
project = ::Project.find(project_id)
new(cluster, project)
end
def calculate_reactive_cache(*)
# read_services calls knative_client.discover implicitily. If we stop
# detecting services but still want to detect knative, we'll need to
# explicitily call: knative_client.discover
#
# We didn't create it separately to avoid 2 cluster requests.
ksvc = read_services
pods = knative_client.discovered ? read_pods : []
{ services: ksvc, pods: pods, knative_detected: knative_client.discovered }
end
def services
return [] unless search_namespace
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
cached_data.to_h.fetch(:services, [])
end
def cache_args
[cluster.id, project.id]
end
def service_pod_details(service)
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
cached_data.to_h.fetch(:pods, []).select do |pod|
filter_pods(pod, service)
end
end
def knative_detected
cached_data = with_reactive_cache_memoized(*cache_args) { |data| data }
knative_state = cached_data.to_h[:knative_detected]
return KNATIVE_STATES['checking'] if knative_state.nil?
return KNATIVE_STATES['installed'] if knative_state
KNATIVE_STATES['uninstalled']
end
def model_name
self.class.name.underscore.tr('/', '_')
end
private
def search_namespace
@search_namespace ||= cluster.kubernetes_namespace_for(project)
end
def knative_client
cluster.kubeclient.knative_client
end
def filter_pods(pod, service)
pod["metadata"]["labels"]["serving.knative.dev/service"] == service
end
def read_services
knative_client.get_services(namespace: search_namespace).as_json
rescue Kubeclient::ResourceNotFoundError
[]
end
def read_pods
cluster.kubeclient.core_client.get_pods(namespace: search_namespace).as_json
end
def id
nil
end
end
end
...@@ -14,15 +14,16 @@ module Projects ...@@ -14,15 +14,16 @@ module Projects
knative_services.flatten.compact knative_services.flatten.compact
end end
# Possible return values: Clusters::Cluster::KnativeServicesFinder::KNATIVE_STATE # Possible return values: Clusters::KnativeServicesFinder::KNATIVE_STATE
def knative_installed def knative_installed
states = @clusters.map do |cluster| states = @clusters.map do |cluster|
cluster.application_knative
cluster.knative_services_finder(project).knative_detected.tap do |state| cluster.knative_services_finder(project).knative_detected.tap do |state|
return state if state == ::Clusters::Cluster::KnativeServicesFinder::KNATIVE_STATES['checking'] # rubocop:disable Cop/AvoidReturnFromBlocks return state if state == ::Clusters::KnativeServicesFinder::KNATIVE_STATES['checking'] # rubocop:disable Cop/AvoidReturnFromBlocks
end end
end end
states.any? { |state| state == ::Clusters::Cluster::KnativeServicesFinder::KNATIVE_STATES['installed'] } states.any? { |state| state == ::Clusters::KnativeServicesFinder::KNATIVE_STATES['installed'] }
end end
def service(environment_scope, name) def service(environment_scope, name)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
require 'spec_helper' require 'spec_helper'
describe Clusters::Cluster::KnativeServicesFinder do describe Clusters::KnativeServicesFinder do
include KubernetesHelpers include KubernetesHelpers
include ReactiveCachingHelpers include ReactiveCachingHelpers
......
...@@ -40,7 +40,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do ...@@ -40,7 +40,7 @@ describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
it do it do
expect(subject.knative_services_finder(subject.project)) expect(subject.knative_services_finder(subject.project))
.to be_instance_of(Clusters::Cluster::KnativeServicesFinder) .to be_instance_of(Clusters::KnativeServicesFinder)
end end
describe '.enabled' do describe '.enabled' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment