Skip to content

Commit 416d604

Browse files
committed
feat(*) lazy load api
1 parent 9b65710 commit 416d604

File tree

2 files changed

+43
-34
lines changed

2 files changed

+43
-34
lines changed

src/resty/aws/init.lua

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ local build_request = require("resty.aws.request.build")
66
local sign_request = require("resty.aws.request.sign")
77
local execute_request = require("resty.aws.request.execute")
88
local split = require("pl.utils").split
9+
local tablex = require("pl.tablex")
910

1011

1112

@@ -70,44 +71,54 @@ AWS.__index = lookup_helper
7071

7172

7273

73-
local aws_config do
74-
aws_config = {
75-
region = require("resty.aws.raw-api.region_config_data"),
76-
api = {},
77-
}
74+
local aws_config = {
75+
region = require("resty.aws.raw-api.region_config_data"),
76+
api = {},
77+
}
7878

79+
local load_api
80+
do
7981
-- The API table is a map, where the index is the service-name. The value is a table.
8082
-- The table is another map, indexed by version (string). The value of that one
8183
-- is the raw AWS api.
8284
-- That raw-api is loaded upon demand by meta-table magic so we only load what we need.
8385
local list = require("resty.aws.raw-api.table_of_contents")
84-
for i, filename in ipairs(list) do
86+
local apis = {}
87+
for _, filename in ipairs(list) do
8588
-- example filename: "AWSMigrationHub-2017-05-31"
8689
local module_name = "resty.aws.raw-api." .. filename
8790
-- example module_name: "resty.aws.raw-api.AWSMigrationHub-2017-05-31"
88-
local service_name, version = assert(filename:match("^(.-)%-(%d%d%d%d%-%d%d%-%d%d)$"))
89-
-- example service_name: "AWSMigrationHub"
91+
-- example table_of_contents: "MigrationHub:AWSMigrationHub-2017-05-31"
92+
local service_id, _, version = assert(filename:match("^(.-)%:(.-)%-(%d%d%d%d%-%d%d%-%d%d)$"))
93+
-- example service_id: "MigrationHub"
9094
-- example version: "2017-05-31"
91-
local service_table = aws_config.api[service_name]
92-
if not service_table then
93-
service_table = {}
94-
aws_config.api[service_name] = service_table
95-
end
96-
-- load the file and dereference shapes
97-
local api = require(module_name)
98-
dereference_service(api)
95+
local service_table = apis[service_id] or {}
96+
service_table[version] = module_name
9997

100-
service_table[version] = api
98+
local sorted_versions = table.sort(tablex.keys(service_table))
99+
service_table.latest = service_table[sorted_versions[#service_table]]
101100

102-
if service_table.latest then
103-
-- update 'latest' if this one is newer
104-
if service_table.latest.metadata.apiVersion < version then
105-
service_table.latest = api
106-
end
107-
else
108-
-- we're the only one, and hence also 'latest' so far
109-
service_table.latest = api
101+
apis[service_id] = service_table
102+
end
103+
104+
local cache = setmetatable({}, { __mode = "v" })
105+
106+
function load_api(service, version)
107+
local module_name = apis[service] and apis[service][version]
108+
if not module_name then
109+
return nil, "unknown service: " .. tostring(service) .. "/" .. tostring(version)
110+
end
111+
112+
local api = cache[module_name]
113+
if api then
114+
return api
110115
end
116+
117+
api = require(module_name)
118+
dereference_service(api)
119+
120+
cache[module_name] = api
121+
return api
111122
end
112123
end
113124

@@ -378,13 +389,9 @@ function AWS:new(config)
378389
end
379390

380391
-- create service methods/constructors
381-
for service_name, versions in pairs(aws_config.api) do
392+
for service_id in pairs(aws_config.api) do
382393
-- Create service specific functions, by `serviceId`
383-
384-
local serviceId = versions[next(versions)].metadata.serviceId
385-
local cleanId = serviceId:gsub(" ", "") -- for interface drop all spaces
386-
387-
aws_instance[cleanId] = function(aws, config)
394+
aws_instance[service_id] = function(aws, config)
388395
if getmetatable(aws) ~= AWS then
389396
error("must instantiate AWS services by calling aws_instance:ServiceName(config)", 2)
390397
end
@@ -404,9 +411,9 @@ function AWS:new(config)
404411

405412
-- create the service
406413
-- `config.apiVersion`: the api version to use
407-
local api = versions[service_config.apiVersion]
414+
local api = load_api(service_id, service_config.apiVersion)
408415
if not api then
409-
return nil, ("service '%s' does not have an apiVersion '%s'"):format(serviceId, tostring(service_config.apiVersion))
416+
return nil, ("service '%s' does not have an apiVersion '%s'"):format(service_id, tostring(service_config.apiVersion))
410417
end
411418
if service_config.apiVersion == "latest" then
412419
service_config.apiVersion = api.metadata.apiVersion

update_api_files.sh

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,11 @@ FILENAME=$TARGET/table_of_contents.lua
5353
echo "adding: $FILENAME"
5454
echo "return {" >> $FILENAME
5555
for f in "${file_list[@]}"; do
56+
source_file=$SOURCE/apis/$f.normal.json
57+
service_id=$(jq -r '.metadata.serviceId' $source_file | tr -d ' ')
5658
# replace . with - since . can't be in a Lua module name
5759
f=${f//./-}
58-
echo ' "'"$f"'",' >> $FILENAME
60+
echo ' "'"$service_id:$f"'",' >> $FILENAME
5961
done
6062
echo "}" >> $FILENAME
6163

0 commit comments

Comments
 (0)