Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unified cache implementation for V2 and V3 #1222

Merged
merged 4 commits into from Nov 13, 2015
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 9 additions & 27 deletions src/Paket.Core/NuGetV2.fs
Expand Up @@ -252,33 +252,15 @@ let deleteErrorFile (packageName:PackageName) =
with
| _ -> ()

let getDetailsFromNuGet force auth nugetURL packageName version =
getDetailsFromCacheOr
force
nugetURL
packageName
version
(fun () ->
getDetailsFromNuGetViaOData auth nugetURL packageName version)

/// Tries to get download link and direct dependencies from NuGet
/// Caches calls into json file
let getDetailsFromNuGet force auth nugetURL (packageName:PackageName) (version:SemVerInfo) =
let cacheFile,errorFile = cacheFile nugetURL packageName version
async {
try
if not force && errorFile.Exists then
failwithf "Error file for %O exists at %s" packageName errorFile.FullName

let! (invalidCache,details) = loadFromCacheOrODataOrV3 force cacheFile.FullName (auth,nugetURL) packageName version

verbosefn "loaded details for '%O@%O' from url '%s'" packageName version nugetURL

errorFile.Delete()
if invalidCache then
try
File.WriteAllText(cacheFile.FullName,JsonConvert.SerializeObject(details))
with
| _ -> () // if caching fails we should not fail
return details
with
| exn ->
File.AppendAllText(errorFile.FullName,exn.ToString())
raise exn
return! getDetailsFromNuGetViaOData auth nugetURL packageName version
}

let fixDatesInArchive fileName =
try
Expand Down Expand Up @@ -481,7 +463,7 @@ let DownloadPackage(root, auth, (source : PackageSource), groupName, packageName
let url, nugetPackage =
match source with
| Nuget source ->
source.Url, (getDetailsFromNuGet force auth source.Url packageName version)
source.Url, (getDetailsFromNuGet force auth source.Url packageName version)
| NugetV3 source ->
source.Url, (NuGetV3.GetPackageDetails force source packageName version)
| _ -> failwith "shouldnt be here"
Expand Down
28 changes: 7 additions & 21 deletions src/Paket.Core/NuGetV3.fs
Expand Up @@ -224,24 +224,10 @@ let loadFromCacheOrGetDetails (force:bool)

/// Uses the NuGet v3 registration endpoint to retrieve package details .
let GetPackageDetails (force:bool) (source:NugetV3Source) (packageName:PackageName) (version:SemVerInfo) : Async<NuGet.NugetPackageCache> =
let cacheFile,errorFile = NuGet.cacheFile source.Url packageName version
async {
try
if not force && errorFile.Exists then
failwithf "Error file for %O exists at %s" packageName errorFile.FullName

let! (invalidCache,details) = loadFromCacheOrGetDetails force cacheFile.FullName source packageName version

errorFile.Delete()
if invalidCache then
try
File.WriteAllText(cacheFile.FullName,JsonConvert.SerializeObject(details))
with
| _ -> () // if caching fails we should not fail
return details
with
| exn ->
File.AppendAllText(errorFile.FullName,exn.ToString())
raise exn
return! getPackageDetails source packageName version
}
getDetailsFromCacheOr
force
source.Url
packageName
version
(fun () ->
getPackageDetails source packageName version)
43 changes: 40 additions & 3 deletions src/Paket.Core/Nuget.fs
Expand Up @@ -4,9 +4,12 @@ module Paket.NuGet
open Paket.Utils
open Paket.Domain
open Paket.Requirements
open Paket.Logging

open System.IO

open Newtonsoft.Json

type NugetPackageCache =
{ Dependencies : (PackageName * VersionRequirement * FrameworkRestrictions) list
PackageName : string
Expand All @@ -30,6 +33,40 @@ let inline normalizeUrl(url:string) = url.Replace("https","http").Replace("www."
let cacheFile nugetURL (packageName:PackageName) (version:SemVerInfo) =
let h = nugetURL |> normalizeUrl |> hash |> abs
let packageUrl = sprintf "%O.%s.s%d.json" packageName (version.Normalize()) h
let cacheFile = FileInfo(Path.Combine(CacheFolder,packageUrl))
let errorFile = FileInfo(cacheFile.FullName + ".failed")
cacheFile, errorFile
FileInfo(Path.Combine(CacheFolder,packageUrl))


let getDetailsFromCacheOr force nugetURL (packageName:PackageName) (version:SemVerInfo) (get : unit -> NugetPackageCache Async) : NugetPackageCache Async =
let cacheFile = cacheFile nugetURL packageName version
let get() =
async {
let! result = get()
File.WriteAllText(cacheFile.FullName,JsonConvert.SerializeObject(result))
return result
}
async {
if not force && cacheFile.Exists then
let json = File.ReadAllText(cacheFile.FullName)
let result =
try
let cachedObject = JsonConvert.DeserializeObject<NugetPackageCache> json
Choice1Of2 cachedObject
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just for sake of keeping the project uniform, can you please use the chessie types? Success and Fail IIRC

with
| exn ->
Choice2Of2 exn
return!
match result with
| Choice1Of2 cachedObject ->
if cachedObject.CacheVersion <> NugetPackageCache.CurrentCacheVersion then
cacheFile.Delete()
get()
else
async { return cachedObject }
| Choice2Of2 exn ->
traceWarnfn "Error loading from cache for package '%s.%s':\n%s" (packageName.ToString())
(version.ToString())
(exn.ToString())
get()
else
return! get()
}