From 0437444247f25cb936f483b6da3b4457c6ed79a4 Mon Sep 17 00:00:00 2001 From: f Date: Thu, 2 Jan 2020 20:20:41 -0300 Subject: [PATCH] optimizacion: solo leer el contenido de los docs cuando se los necesite --- app/models/post.rb | 23 ++++++++++++++++++----- app/models/site.rb | 8 ++------ config/initializers/core_extensions.rb | 6 ++++++ test/models/post_test.rb | 2 +- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 3e838e0..8b851ad 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true -require 'jekyll/utils' - # Esta clase representa un post en un sitio jekyll e incluye métodos # para modificarlos y crear nuevos. # @@ -15,6 +13,15 @@ class Post < OpenStruct PRIVATE_ATTRIBUTES = %i[path slug attributes errors].freeze PUBLIC_ATTRIBUTES = %i[lang date].freeze + class << self + # Obtiene el layout sin leer el Document + def find_layout(doc) + SafeYAML.load(IO.foreach(doc.path).lazy.grep(/^layout: /).take(1).first) + .try(:[], 'layout') + .try(:to_sym) + end + end + # Redefinir el inicializador de OpenStruct # # @param site: [Site] el sitio en Sutty @@ -33,6 +40,10 @@ class Post < OpenStruct # MetadataFactory devuelve un tipo de campo por cada campo. A # partir de ahí se pueden obtener los valores actuales y una lista # de valores por defecto. + # + # XXX: En el primer intento de hacerlo más óptimo, movimos esta + # lógica a instanciación bajo demanda, pero no solo no logramos + # optimizar sino que aumentamos el tiempo de carga :/ layout.metadata.each_pair do |name, template| send "#{name}=".to_sym, MetadataFactory.build(document: document, @@ -47,13 +58,15 @@ class Post < OpenStruct required: template['required']) end + # TODO: Llamar dinámicamente load_lang! load_slug! load_date! load_path! - # Leer el documento - read + # XXX: No usamos Post#read porque a esta altura todavía no sabemos + # nada del Document + document.read! if File.exist? document.path end def id @@ -172,7 +185,7 @@ class Post < OpenStruct return unless written? document.path = path.absolute - document.read + document.read! end def new? diff --git a/app/models/site.rb b/app/models/site.rb index e82a347..9d73424 100644 --- a/app/models/site.rb +++ b/app/models/site.rb @@ -176,14 +176,10 @@ class Site < ApplicationRecord @posts[lang] = PostRelation.new site: self - # Jekyll lee los documentos en orden cronológico pero los invierte - # durante la renderización. Usamos el orden cronológico inverso por - # defecto para mostrar los artículos más nuevos primero. - docs = collections[lang.to_s].try(:docs).try(:sort) { |a, b| b <=> a } # No fallar si no existe colección para este idioma # XXX: queremos fallar silenciosamente? - (docs || []).each do |doc| - layout = layouts[doc.data['layout'].to_sym] + (collections[lang.to_s].try(:docs) || []).each do |doc| + layout = layouts[Post.find_layout(doc)] @posts[lang].build(document: doc, layout: layout, lang: lang) end diff --git a/config/initializers/core_extensions.rb b/config/initializers/core_extensions.rb index 66003a0..be44139 100644 --- a/config/initializers/core_extensions.rb +++ b/config/initializers/core_extensions.rb @@ -27,4 +27,10 @@ module Jekyll ThemeAssetsReader.class_eval do def read; end end + + # Prevenir la lectura del documento + Document.class_eval do + alias_method :read!, :read + def read; end + end end diff --git a/test/models/post_test.rb b/test/models/post_test.rb index 8528072..82a06cb 100644 --- a/test/models/post_test.rb +++ b/test/models/post_test.rb @@ -82,7 +82,7 @@ class PostTest < ActiveSupport::TestCase document = Jekyll::Document.new(@post.path.value, site: @site.jekyll, collection: collection) - document.read + document.read! assert document.data['categories'].include?(title) assert_equal title, document.data['title']