11
11
using Elastic . Markdown . IO . State ;
12
12
using Elastic . Markdown . Links . CrossLinks ;
13
13
14
- await LambdaBootstrapBuilder . Create ( Handler )
15
- . Build ( )
16
- . RunAsync ( ) ;
14
+ const string bucketName = "elastic-docs-link-index" ;
17
15
16
+ // await LambdaBootstrapBuilder.Create(Handler)
17
+ // .Build()
18
+ // .RunAsync();
19
+
20
+ // Uncomment to test locally without uploading
21
+ await CreateLinkIndex ( new AmazonS3Client ( ) ) ;
22
+
23
+ #pragma warning disable CS8321 // Local function is declared but never used
18
24
static async Task < string > Handler ( ILambdaContext context )
25
+ #pragma warning restore CS8321 // Local function is declared but never used
19
26
{
20
27
var sw = Stopwatch . StartNew ( ) ;
28
+
21
29
IAmazonS3 client = new AmazonS3Client ( ) ;
22
- var bucketName = "elastic-docs-link-index" ;
30
+ var linkIndex = await CreateLinkIndex ( client ) ;
31
+ if ( linkIndex == null )
32
+ return $ "Error encountered on server. getting list of objects.";
33
+
34
+ var json = LinkIndex . Serialize ( linkIndex ) ;
35
+
36
+ using var stream = new MemoryStream ( Encoding . UTF8 . GetBytes ( json ) ) ;
37
+ await client . UploadObjectFromStreamAsync ( bucketName , "link-index.json" , stream , new Dictionary < string , object > ( ) , CancellationToken . None ) ;
38
+ return $ "Finished in { sw } ";
39
+ }
40
+
41
+
42
+ static async Task < LinkIndex ? > CreateLinkIndex ( IAmazonS3 client )
43
+ {
23
44
var request = new ListObjectsV2Request
24
45
{
25
46
BucketName = bucketName ,
26
- MaxKeys = 5
47
+ MaxKeys = 1000 //default
27
48
} ;
28
49
29
50
var linkIndex = new LinkIndex
@@ -32,20 +53,23 @@ static async Task<string> Handler(ILambdaContext context)
32
53
} ;
33
54
try
34
55
{
56
+ var httpClient = new HttpClient ( ) ;
35
57
ListObjectsV2Response response ;
36
58
do
37
59
{
38
60
response = await client . ListObjectsV2Async ( request , CancellationToken . None ) ;
39
- foreach ( var obj in response . S3Objects )
61
+ await Parallel . ForEachAsync ( response . S3Objects , async ( obj , ctx ) =>
40
62
{
41
63
if ( ! obj . Key . StartsWith ( "elastic/" , StringComparison . OrdinalIgnoreCase ) )
42
- continue ;
64
+ return ;
43
65
44
66
var tokens = obj . Key . Split ( '/' ) ;
45
67
if ( tokens . Length < 3 )
46
- continue ;
68
+ return ;
47
69
48
- var gitReference = await ReadLinkReferenceSha ( client , obj ) ;
70
+ // TODO create a dedicated state file for git configuration
71
+ // Deserializing all of the links metadata adds significant overhead
72
+ var gitReference = await ReadLinkReferenceSha ( httpClient , obj ) ;
49
73
50
74
var repository = tokens [ 1 ] ;
51
75
var branch = tokens [ 2 ] ;
@@ -67,39 +91,36 @@ static async Task<string> Handler(ILambdaContext context)
67
91
{ branch , entry }
68
92
} ) ;
69
93
}
70
-
71
- Console . WriteLine ( entry ) ;
72
- }
94
+ } ) ;
73
95
74
96
// If the response is truncated, set the request ContinuationToken
75
97
// from the NextContinuationToken property of the response.
76
98
request . ContinuationToken = response . NextContinuationToken ;
77
99
} while ( response . IsTruncated ) ;
78
100
}
79
- catch ( AmazonS3Exception ex )
101
+ catch
80
102
{
81
- return $ "Error encountered on server. Message:' { ex . Message } ' getting list of objects." ;
103
+ return null ;
82
104
}
83
105
84
- var json = LinkIndex . Serialize ( linkIndex ) ;
85
-
86
- using var stream = new MemoryStream ( Encoding . UTF8 . GetBytes ( json ) ) ;
87
- await client . UploadObjectFromStreamAsync ( bucketName , "link-index.json" , stream , new Dictionary < string , object > ( ) , CancellationToken . None ) ;
88
- return $ "Finished in { sw } ";
106
+ return linkIndex ;
89
107
}
90
108
91
- static async Task < string > ReadLinkReferenceSha ( IAmazonS3 client , S3Object obj )
109
+ static async Task < string > ReadLinkReferenceSha ( HttpClient httpClient , S3Object obj )
92
110
{
93
111
try
94
112
{
95
- var contents = await client . GetObjectAsync ( obj . Key , obj . Key , CancellationToken . None ) ;
96
- await using var s = contents . ResponseStream ;
97
- var linkReference = LinkReference . Deserialize ( s ) ;
113
+ // can not use client getobject since CRT checksum validation requires native code not available in AOT.
114
+ var tokens = obj . Key . Split ( '/' ) ;
115
+ var path = Path . Join ( tokens [ 0 ] , tokens [ 1 ] , "tree" , tokens [ 2 ] , string . Join ( "/" , tokens [ 3 ..] ) ) ;
116
+ var url = "https://docs-v3-preview.elastic.dev/" + path ;
117
+ var json = await httpClient . GetStringAsync ( new Uri ( url ) ) ;
118
+
119
+ var linkReference = LinkReference . Deserialize ( json ) ;
98
120
return linkReference . Origin . Ref ;
99
121
}
100
- catch ( Exception e )
122
+ catch
101
123
{
102
- Console . WriteLine ( e ) ;
103
124
// it's important we don't fail here we need to fallback gracefully from this so we can fix the root cause
104
125
// of why a repository is not reporting its git reference properly
105
126
return "unknown" ;
0 commit comments