1. 前言

在前面的文章中我们聊过cocoapods-downloader这个库,其中也简单提到了一些问题,所以顺势将涉及到cocoapods缓存相关的问题一起拿出来说下。本文内容主要分为两部分,一部分是存在的问题(当然只限于我已知的),另一部分是可能的优化点,每个点GitHub我都会进行分析和给出自己的方案,可能不够完美,可指针能仅仅是一个初步设计。需要注意的是,和缓存有关的内容会涉及两个独github中文社区立的gem:cocoapods 和 cocoapods-downloader。

  • 涉及资源

    • cocoapods:1.11.2
    • cocoapods-downloader:1.指针5.github永久回家地址1
  • 这篇文章阅读后可以带缓存清理来什么?

    阅读完本文后将对cocoapods缓存部分有一定的理解,增加你遇到奇怪缓存问题后的解决问题的一些经验。

  • 阅读要求

    基本上没啥要求,有一定giti的cocoapods使用经验即可。

  • 阅读准备

    • 为了描述方便,我们将cocoapods的sandbox缓存(也就是Pods目录下)称之为【近缓存指针的拼音】,将~/Library/CGitache/Cocoapods目录的全局缓存称之为【远缓存】。
    • pod缓存是什么意思分为release和external两种类型,release指针电影 pod是发布到source中的pod,external pod是通过在Podfile中使用诸如:git/:path/:podspec这类的pod。

2. 问题

2.1 Git浅克隆丢失

  • 背景

    Git浅克隆大家应该都了解,不了解的可以去网上了解一下,主要目的旨在于能够尽量下载你所需要的仓库部分,这样能够大大github下载增加你的下载效率,所以这部分产生的丢失问题主要是会在特定github官网情况下拖慢你的下载效率。而具体场景是:当你使用external pod,Git并通过:git && :b缓存视频怎样转入本地视频ran缓存视频怎样转入本地视频ch的方式进行pod声明,在执行pod install时,会导致下载完指针万用表的使用方法整的仓库,而失去浅克隆的效率。

  • 分析

    这个指针式万用表问题出现的原因实际上来自于一次优化操作的PR,作者发github汤姆现一个缓存问题缓存:当你使用external pod,并通过:git && :branch的方式进行pod声明,如果近缓存不可用而去找远缓存,而在访问GitHub远缓存时,使用:git:branch作为参github官网数来计算的key,和下载后缓存用的key的github中文社区所需参数是不同的,所以这将导致远缓存永远无法被命中:

    • external pod的缓存key计算github永久回家地址

      #{name}#{request.params.MD5缓存}-#{spec.sha1[0,5]}

    • release pod的缓存key计算

      #{name}#{version指针数组和数组指针的区别}-#{spec.sha1[0,5]}

    所以作者提出一个方案,通过提前查询远程仓库的某个branch对应的具体commit,作为一个预处理过程将参数进行github开放私库转化,而后参与缓存key的计算时只使用commit,这在查询缓存和下载后缓存时将使用同样的参数。

    • 为什么使用GitHub:branch时,查询缓存时的参数和下载后缓存的参数是不同的?

      因为在git的设计中,branch是一个动态的指针,它可以指向任何commit,所以使用branch参数来指代一个缓存资源时,其是无法保证相对的唯一性giti轮胎的。所以cocoapods的处理逻辑上是这样:在指针的拼音下载后缓存时,将判断下载资源参数是否能够代表一个唯一的资源,如果能,缓存用的参数就直接使用下载参数,否则获取github汤姆它的缓存视频在手机哪里找checkout_options:

      # cocoapods/lib/cocoapods/downloader.rb
      def self.download_source(target, params)
          FileUtils.rm_rf(target)
          downloader = Downloader.for_target(target, params)
          downloader.download
          target.mkpath
          if downloader.options_specific?
            params
          else
            downloader.checkout_options
          end
      end
      

      而对于git downgithub是干什么的loader的checkout options,其内容是:

      # cocoapods-downloader/lib/cocoapods-downloader/git.rb
      def checkout_options
          options = {}
          options[:git] = url
          options[:commit] = target_git('rev-parse', 'HEAD').chomp
          options[:submodules] = true if self.options[:submodules]
          options
      end
      

      而查询缓存时,请求时能够提供的仅仅是:git:branch参数,所以这导致了查询时的参数和下载后缓存的参数不同;那么release pod是否有这个问git命令题呢?由于release pod的查询缓存和下载后缓存的key计指针电影算依靠的是podspec内容,只要podspec不变,缓存就能正常命中,当然从技术角度来说其由于实质上由于支持ggithub下载it多个参数,所以git命令失效问题也存在,这需要手动进行删除github下载,但是从设计上来说,release pod的发布作者应该确保其唯一性。

    但是其解决方案中直接git命令:branch参数剔除,这也导致了本节要说的浅克隆丢失问题,下面是预处理参数和具体克隆的具体参数生成逻辑:

    • 预处理参指针的拼音

      # cocoapods-downloader/lib/cocoapods-downloader/git.rb
      def self.preprocess_options(options)
        return options unless options[:branch]
        command = ['ls-remote',
                   options[:git],
                   options[:branch]]
        output = Git.execute_command('git', command)
        match = commit_from_ls_remote output, options[:branch]
        return options if match.nil?
        options[:commit] = match
        options.delete(:branch)
        options
      end
      
    • 克隆参数生成

      # cocoapods-downloader/lib/cocoapods-downloader/git.rb
      def clone_arguments(force_head, shallow_clone)
      	command = ['clone', url, target_path, '--template=']
        if shallow_clone && !options[:commit]
            command += %w(--single-branch --depth 1)
        end
        unless force_head
      	  if tag_or_branch = options[:tag] || options[:branch]
              command += ['--branch', tag_or_branch]
           end
        end
        command
      end
      
  • 如何解决

    具体修复起来并不难,我目前的方案是:在预处理参数时缓存视频在手机哪里找,不移除:branch参数,并在生成克隆参数时有比较大的逻辑改github中文官网网页进,主要是需要保证:branch:commit同时出现时,你需要判定它是由预处理产生的,还是来自于原始的参数中,具体逻辑和思路可以翻阅cocoapods-downloader中这个PR。

    实际上这个浅克隆修复部分也同时能工作在release pod中,但是并不提倡在relgithub是干什么的ease pod的podspec中使用:branch;PR的其他部分优化也完全适用于release pod。

2.2 Sandbox污染问题

  • 背景

    这个问题按照我们现在的上下文可以说是近缓存污染问题,前面的问题顶多增加你的下GitHub载时间,而这个问题出现后会产生莫名其妙的报错,可能会增加你不少的排查时间,可以说这缓存是什么意思是一个gitee设计中的明显缺陷。

    如果你github打不开有一个项github中文社区目仓库有两个分支A和B,A分支依赖PodX的1.0版本,B分支依赖github中文社区PodX的github下载2.0版本,一开始你指针万用表的使用方法在A分支中执行pod install,成功后,你切换到B分支,重新执行pod install,并在它执行完成之缓存文件夹名称前强制退出这个gitee进程(比如Ctrl + C),这时你再切换到指针式万用表A分支,很可能出现你需要的是PodX的1.0版本,但是实际上近缓存内却是2.0版本,Podfile.lockgithub汤姆和Magithub官网nifest.lock内都显示的是1.0版本,而且你不管如何重新pod install,都无法解决,除github永久回家地址非你手动删除近缓存。

  • 分析

    近缓存存在于项目的Pods目录下缓存的视频怎么保存到本地,其中有一个Manifest.lock文件,这个giti文件记录着你Pods目录下实际的近缓存内容,其中最重要的拿来检测近缓存是否可用的是CHECKOUT OPTIONSSPEC CHECKSUMS,这里我姑且称其为组,CHECKgithub开放私库OUT OPTIONS组作用的是external pod的校验功能,SPEC CHECKSUMS组起到的是release pod的校验功能。在实际pod install的过程中,和此问题相关的部分我将其分为install部分和写入lock部分,其中install部分在判断近缓存是否可用时,与此有关的是对比Podfile.lock文件和Manifest.lock文件内的CHECKOUT OPTIONSSPEC CHECKS缓存视频合并app下载UMS,当内容一样时说明近缓存可用,否则就要去查询远缓存,并且进行可能下载和拷贝到Pods目录内;而写入lock部分发生在所有Pod都已经下载拷贝到Pods之后,所以可能出现的情况是,Pods目录内已经github中文官网网页写入了需要版本的库,但是其Ma指针式万用表表盘详解nifest.缓存文件夹名称lock文件还未被更新就被强制退出,导致Manifest.lock内容无法反映实际的近缓存情况,我称其为被污染了。

  • 如何解决

    我在cocoapods的issues中查到了一个解决此问题github的PR,其主要原理是提出一种近缓存的dirty状态,判断近缓存是否可指针用时,增加一个dirty状态判断,而在下载拷贝时会写入一个代表某个pod dirty状态的文件,在更新完Manifest.lock后再删除dirty文件。目前它还未被合并,在其中我也发现了一个不足,其只解决了release pod的这个问题,却漏掉了external pod的处理。

    当这篇文章写完时,作者已经修复了这个部分。

3. 优化点

说完了问题,现在开始说说可以优化的地方。

3.1 Git HEAD预处理

  • 背景

    当你使用external pod,并仅仅指定:git地址,而不指定任何其他参数,此时会导致后期的远缓存访问将永远不命中。

  • 分析

    和前面提到对于:github官网branch无法反映一个唯一资源是同一个问题。

  • 如何解决

    所以,对:branch的优化,也完全可以适用于没有任何参数的情况缓存视频在手机哪里找,默认没有任何参数时实际会通过远指针数学程的HEAD指针来浅克隆默认的节点,缓存视频合并app下载在预处理参数时,可以增加对没有任何参数的查询远程HEAD处理。

3.2 尽可能的浅克缓存的视频怎么保存到本地

  • 背景

    前面我们都是说在没有:commit时通过远程查询GitHub来得到commit,那么在遇到没有指定其他参数而只有:commit时,是不是也可以反过来呢?不然就需要克隆一个完整的仓库了。

  • 分析

    我们可以通过远程查询所有的指针,是否有指向这个commit的,这样可以尽可缓存视频怎样转入相册能的使用浅克隆。

  • 如何解决

    我们可以在预处理参数时也增加这种情况的处理,目前还没写github中文官网网页代码,只提出了建议,或许大家都喜欢指针数学这种想法后再写代码更合适。

    这个部分的优化同时适用于release pod和external pod。

3.3 提高Git远缓存的复用率

  • 背景

    github中文社区际上前面的2.1浅克隆丢失问题的修复中,会导致缓存清理一个问题:由于gitlab保留了:branc指针数组h参数,对于远缓存目录内已有的旧缓存,之前指定:branch时参与key计算的只有:git:commgithub中文官网网页it参数,而如果这个修复代码生效,参与key计算的将包含:git && :commit && :branch,不过这也只影响部分旧缓存的不可用。

    一开始我想的是增加参数过滤,在生成缓存视频在手机哪里找key的计算前,将:brancgitlabh过滤掉,这样就能保证和旧的远缓存github是干什么的兼容了。但是又想到有其他的问题:只要参数不同,远缓存就无法复用,哪怕实际github中文官网网页上是同样的内容,比如使缓存清理用external pod,指定:git && :tag,后面改成了:git && :commit,但实际上这个tag对应和commit和本次的commit实际上是一样的。

  • 分析

    对于这个问题,究其根本是因为参与key计算的参数有冗余,对于一个gitgithub下载仓库内,能够保证唯一性的只有commit,其他的参数都是冗余的,我们完全可以去掉,哪怕是tag。

  • 如何解决

    在预处理都能获取commit的前提下,参与缓存key计算的部分和lock文件内的CHECKOUT OPTIONS部分过滤掉:git &github中文社区amp;& :commit以外的其他参数。

4. 结尾

感谢阅读,本指针数组文主要讨论的问题都是针对于git,之所以没有指出其他协议的问题,是因为我很少用,所以暂时没关注。文中不免有很多主观想法和一些勘误,或Git者你认为不对缓存视频怎样转入相册的地方,如果能和我聊聊或者评论留下你的想法,非常欢迎!

参考资料

  • github.com/CocoaPods/C…
  • github.com/CocoaPods/cgitee