Skip to content

Commit c5c3efd

Browse files
committed
feat(search): KTL-1516: use separate build for collecting page_views
1 parent 39e3b23 commit c5c3efd

File tree

4 files changed

+106
-80
lines changed

4 files changed

+106
-80
lines changed

.teamcity/builds/kotlinlang/buidTypes/BuildSearchIndex.kt

Lines changed: 9 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,18 @@ import jetbrains.buildServer.configs.kotlin.buildSteps.ScriptBuildStep
1010
import jetbrains.buildServer.configs.kotlin.buildSteps.script
1111
import jetbrains.buildServer.configs.kotlin.triggers.schedule
1212
import vcsRoots.KotlinLangOrg
13-
import java.io.File
14-
import java.nio.file.Paths
15-
16-
private fun readScript(name: String): String {
17-
val file = File(Paths.get("scripts/$name.mjs").toAbsolutePath().toString())
18-
return file.readText()
19-
}
2013

2114
object BuildSearchIndex : BuildType({
2215
name = "Build Site Search Index"
2316
description = "Build search index for Algolia using Google Analytics data"
2417

2518
params {
26-
param("env.KEY_FILE_LOCATION", "/secrets/google-credentials.json")
2719
param("virtualenv.folder", "_environment")
2820
param("env.WH_INDEX_NAME", SEARCH_INDEX_NAME)
2921
param("env.WH_SEARCH_USER", SEARCH_APP_ID)
3022
param("env.WH_SEARCH_KEY", "%ALGOLIA_WRITE_API_KEY%")
3123
}
3224

33-
artifactRules = """
34-
page_views_list.json
35-
page_views_map.json
36-
""".trimIndent()
37-
3825
vcs {
3926
root(KotlinLangOrg)
4027

@@ -43,26 +30,10 @@ object BuildSearchIndex : BuildType({
4330
}
4431

4532
steps {
46-
script {
47-
name = "Prepare page views"
48-
scriptContent = """
49-
#!/usr/bin/env bash
50-
":" //# comment; exec /usr/bin/env node --input-type=module - "${'$'}@" < "${'$'}0"
51-
52-
${readScript("stats/pageviews")}
53-
""".trimIndent()
54-
dockerImage = "node:lts-slim"
55-
dockerImagePlatform = ScriptBuildStep.ImagePlatform.Linux
56-
dockerPull = true
57-
}
5833
script {
5934
name = "Push search index"
6035
scriptContent = """
61-
#!/bin/bash
62-
63-
## refresh packages
64-
pip install -r requirements.txt
65-
36+
#!/bin/bash
6637
python kotlin-website.py index
6738
""".trimIndent()
6839
dockerImage = "%dep.Kotlin_KotlinSites_Builds_KotlinlangOrg_BuildPythonContainer.kotlin-website-image%"
@@ -96,11 +67,14 @@ object BuildSearchIndex : BuildType({
9667
onDependencyCancel = FailureAction.CANCEL
9768
}
9869

99-
artifacts(AbsoluteId("WebTeam_BuildsForDeploymentJetBrainsCom_Algolia_PageViewsFromGoogle")) {
100-
buildRule = lastSuccessful()
101-
artifactRules = """
102-
+:unique_pageviews_pages_000000000000.json => data
103-
""".trimIndent()
70+
dependency(PageViews) {
71+
snapshot {}
72+
73+
artifacts {
74+
artifactRules = """
75+
page_views_map.json => data/
76+
""".trimIndent()
77+
}
10478
}
10579

10680
dependency(BuildSitePages) {
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,58 @@
11
package builds.kotlinlang.buidTypes
22

3+
import jetbrains.buildServer.configs.kotlin.AbsoluteId
34
import jetbrains.buildServer.configs.kotlin.BuildType
5+
import jetbrains.buildServer.configs.kotlin.buildSteps.ScriptBuildStep
6+
import jetbrains.buildServer.configs.kotlin.buildSteps.script
7+
import jetbrains.buildServer.configs.kotlin.triggers.finishBuildTrigger
8+
import java.io.File
9+
import java.nio.file.Paths
10+
11+
private fun readScript(name: String): String {
12+
val file = File(Paths.get("scripts/$name.mjs").toAbsolutePath().toString())
13+
return file.readText()
14+
}
15+
16+
private val pageViewsCollectId = AbsoluteId("WebTeam_BuildsForDeploymentJetBrainsCom_Algolia_PageViewsFromGoogle")
417

518
object PageViews : BuildType({
619
name = "Fetch Page Views"
720
description = "Build data files with page views statistics for kotlin websites"
21+
22+
artifactRules = """
23+
page_views_list.json
24+
page_views_map.json
25+
""".trimIndent()
26+
27+
triggers {
28+
finishBuildTrigger {
29+
buildType = pageViewsCollectId.absoluteId
30+
branchFilter = "+:<default>"
31+
successfulOnly = true
32+
}
33+
}
34+
35+
steps {
36+
script {
37+
name = "Prepare page views"
38+
scriptContent = """
39+
#!/usr/bin/env bash
40+
":" //# comment; exec /usr/bin/env node --input-type=module - "${'$'}@" < "${'$'}0"
41+
42+
${readScript("stats/pageviews")}
43+
""".trimIndent()
44+
dockerImage = "node:lts-slim"
45+
dockerImagePlatform = ScriptBuildStep.ImagePlatform.Linux
46+
dockerPull = true
47+
}
48+
}
49+
50+
dependencies {
51+
artifacts(pageViewsCollectId) {
52+
buildRule = lastSuccessful()
53+
artifactRules = """
54+
+:unique_pageviews_pages_000000000000.json => data
55+
""".trimIndent()
56+
}
57+
}
858
})

.teamcity/scripts/stats/pageviews.mjs

Lines changed: 46 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { open } from 'node:fs/promises';
33
const INPUT_FILE_PATH = 'data/unique_pageviews_pages_000000000000.json';
44
const input = await open(INPUT_FILE_PATH, 'r');
55

6-
async function openReportFile() {
7-
const file = await open('page_views_list.json', 'w');
6+
async function openReportFile(name) {
7+
const file = await open(name, 'w');
88
await file.truncate(0);
99
return file;
1010
}
@@ -14,59 +14,61 @@ const [listViews, mapViews] = await Promise.all([
1414
openReportFile('page_views_map.json'),
1515
]);
1616

17-
async function append(line) {
18-
const { webpage: url, unique_pageviews: views } = JSON.parse(line);
17+
try {
18+
async function append(line) {
19+
const { webpage: url, unique_pageviews: views } = JSON.parse(line);
1920

20-
const pageviews = Number(views);
21+
const pageviews = Number(views);
2122

22-
if (views === '' || isNaN(pageviews)) {
23-
console.warn(`${url} has incorrect unique_pageviews=${views}`);
24-
return;
23+
if (views === '' || isNaN(pageviews)) {
24+
console.warn(`${url} has incorrect unique_pageviews=${views}`);
25+
return;
26+
}
27+
28+
if (pageviews < 1) return;
29+
if (!(new URL(url).host.includes('kotlinlang.org'))) return;
30+
31+
await Promise.all([
32+
listViews.appendFile(JSON.stringify({ url, pageviews }) + ','),
33+
mapViews.appendFile(`${JSON.stringify(url)}: ${pageviews},`),
34+
]);
2535
}
2636

27-
if (pageviews < 1) return;
28-
if (!(new URL(url).host.includes('kotlinlang.org'))) return;
37+
const lines = [];
2938

3039
await Promise.all([
31-
listViews.appendFile(JSON.stringify({ url, pageviews }) + ','),
32-
mapViews.appendFile(`${JSON.stringify(url)}: ${pageviews},`)
40+
listViews.write('['),
41+
mapViews.write('{'),
3342
]);
34-
}
3543

36-
const lines = [];
37-
38-
await Promise.all([
39-
listViews.write('['),
40-
mapViews.write('{')
41-
]);
44+
const readlineInterface = input.readLines();
4245

43-
const readlineInterface = input.readLines();
44-
45-
readlineInterface.on('line', line => {
46-
lines.push(append(line));
47-
});
48-
49-
const waitInputRead = new Promise(resolve => {
50-
readlineInterface.on('close', () => {
51-
resolve();
46+
readlineInterface.on('line', line => {
47+
lines.push(append(line));
5248
});
53-
});
5449

55-
await waitInputRead;
56-
await Promise.all(lines);
50+
const waitInputRead = new Promise(resolve => {
51+
readlineInterface.on('close', () => {
52+
resolve();
53+
});
54+
});
5755

58-
async function replaceLastCharacter(file, ch) {
59-
const { size } = await file.stat();
60-
file.write(ch, size - 1);
61-
}
56+
await waitInputRead;
57+
await Promise.all(lines);
6258

63-
await Promise.all([
64-
replaceLastCharacter(listViews, ']'),
65-
replaceLastCharacter(mapViews, '}'),
66-
]);
59+
async function replaceLastCharacter(file, ch) {
60+
const { size } = await file.stat();
61+
file.write(ch, size - 1);
62+
}
6763

68-
await Promise.all([
69-
input.close(),
70-
listViews.close(),
71-
mapViews.close(),
72-
]);
64+
await Promise.all([
65+
replaceLastCharacter(listViews, ']'),
66+
replaceLastCharacter(mapViews, '}'),
67+
]);
68+
} finally {
69+
await Promise.all([
70+
input.close(),
71+
listViews.close(),
72+
mapViews.close(),
73+
]);
74+
}

src/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
def get_page_views_statistic() -> Dict[str, int]:
1414
print("Acquiring page view statistic")
1515

16-
file = open("page_views_map.json", "r")
16+
file = open("data/page_views_map.json", "r")
1717
page_views = json.load(file)
1818
file.close()
1919

0 commit comments

Comments
 (0)