Skip to content

Commit

Permalink
version 1.1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
Figueiredo Renato authored and cran-robot committed Feb 28, 2024
0 parents commit 41a2cb8
Show file tree
Hide file tree
Showing 100 changed files with 6,073 additions and 0 deletions.
53 changes: 53 additions & 0 deletions DESCRIPTION
@@ -0,0 +1,53 @@
Type: Package
Package: FaaSr
Title: FaaS (Function as a Service) Package
Version: 1.1.2
Authors@R: c(person("Figueiredo", "Renato", role = c("aut", "cre", "ths", "cph"),
email = "renatof@ufl.edu",
comment = c(ORCID = "0000-0001-9841-6060")),
person("Park", "Sungjae", role = "aut"),
person("Mu", "Nan", role = "ctb"),
person("Ku", "Yun-Jung", role = "ctb"),
person("Daneshmand", "Vahid", role = "ctb"),
person("Thomas", "R. Quinn", role = "aut"),
person("Carey", "Cayelan", role = "ctb")
)
Maintainer: Figueiredo Renato <renatof@ufl.edu>
Description: Allows users to create and deploy the workflow with multiple functions
in Function-as-a-Service (FaaS) cloud computing platforms.
The 'FaaSr' package makes it simpler for R developers to use FaaS platforms by providing the following functionality:
1) Parsing and validating a JSON-based payload compliant to 'FaaSr' schema supporting multiple FaaS platforms
2) Invoking user functions written in R in a Docker container (derived from rocker), using a list generated from
the parser as argument
3) Downloading/uploading of files from/to S3 buckets using simple primitives
4) Logging to files in S3 buckets
5) Triggering downstream actions supporting multiple FaaS platforms
6) Generating FaaS-specific API calls to simplify the registering of a user's workflow with a FaaS platform
Supported FaaS platforms:
Apache OpenWhisk <https://openwhisk.apache.org/>
GitHub Actions <https://github.com/features/actions>
Amazon Web Services (AWS) Lambda <https://aws.amazon.com/lambda/>
Supported cloud data storage for persistent storage:
Amazon Web Services (AWS) Simple Storage Service (S3) <https://aws.amazon.com/s3/>.
License: MIT + file LICENSE
URL: https://github.com/FaaSr/FaaSr-package
BugReports: https://github.com/FaaSr/FaaSr-package/issues
Depends: R (>= 3.5.0)
Imports: jsonlite, httr, uuid, paws.application.integration,
paws.compute, paws.storage, paws.security.identity, cli,
jsonvalidate, base64enc, sodium
Suggests: arrow, glue, rmarkdown, paws.common, testthat, knitr
Encoding: UTF-8
RoxygenNote: 7.2.3
NeedsCompilation: no
Packaged: 2024-02-26 18:52:23 UTC; spark
Author: Figueiredo Renato [aut, cre, ths, cph]
(<https://orcid.org/0000-0001-9841-6060>),
Park Sungjae [aut],
Mu Nan [ctb],
Ku Yun-Jung [ctb],
Daneshmand Vahid [ctb],
Thomas R. Quinn [aut],
Carey Cayelan [ctb]
Repository: CRAN
Date/Publication: 2024-02-27 17:40:07 UTC
2 changes: 2 additions & 0 deletions LICENSE
@@ -0,0 +1,2 @@
YEAR: 2024
COPYRIGHT HOLDER: FaaSr authors
99 changes: 99 additions & 0 deletions MD5
@@ -0,0 +1,99 @@
d22d79ac06b72534697fede397a68ee1 *DESCRIPTION
f13f4707c0badccb2b534889576706d1 *LICENSE
5f101c4b07e58fb9f733e172922d1c67 *NAMESPACE
6bfad039f00de1bf53c6752c74459335 *NEWS.md
c4f3140f928d113b7e6a377b24a5358b *R/faasr_abort_on_multiple_invocations.R
8cef63cfdb89583cb57f4b0a8649f6b7 *R/faasr_arrow_s3_bucket.R
093fd00e4445165fa72a308c39e96257 *R/faasr_check_workflow_cycle.R
925c0b32f90be1b4f406a83573c43780 *R/faasr_client_api_aws-lambda.R
2078eb7645c039db66b32b7c0648ef62 *R/faasr_client_api_github-actions.R
1119232dce8b281179fbf6591a477567 *R/faasr_client_api_openwhisk.R
84153ff8ebb4ee63195fbe3b48d78bfa *R/faasr_client_tools.R
a56e7b49b6322484f7d6868185264514 *R/faasr_delete_file.R
cf9a821e3e8d521de335d03866b39372 *R/faasr_get_file.R
4ec6cf6ea0f32fb79427e9beb4e41e5f *R/faasr_get_user_function_args.R
7fe7fba3aad9bdf4e11fb0a193b3717b *R/faasr_init_log_folder.R
18c09eca25fa80bbf3471e9c2a68b550 *R/faasr_lock.R
29da38be3ba54ef83386824f76c55c00 *R/faasr_log.R
70fce4582dc266c9fc9a993df8377cd0 *R/faasr_parse.R
7ff485460b348a8a7f8e882a81824c64 *R/faasr_predecessors_list.R
6845c406bfcf639192c18753feb5901c *R/faasr_put_file.R
1f4340efc453c0376b37d1dd0e89a6d7 *R/faasr_run_user_function.R
7ce72d048dd16e050d3a7b600ab6bf1f *R/faasr_s3_check.R
879e5d1cc6baa47a8b7a056650a2846a *R/faasr_start.R
aec5bd15c72e6dc883948b6ca08359bb *R/faasr_trigger.R
37c662bda5ec204c2124ab644e575a49 *README.md
e3777280869c075445a691d12a11bfe1 *inst/WORDLIST
8d1fbcfb8c893420704a6c6bed8fb096 *man/check_lambda_exists.Rd
738298dab1bc27d961b02355609af1fb *man/check_user_image_exist.Rd
57a6b586a121c04963a4190a7e3c4529 *man/dot-faasr_get_svc.Rd
f078f07bd4150cfb29327a9a6fcd457d *man/execute_command_with_retry.Rd
9160e0ab8194a814a75ba464a478f9ea *man/faasr.Rd
a2ce82c9c622eecb1df9bd3c2f81642d *man/faasr_abort_on_multiple_invocations.Rd
505cbd966233173e4ad6157e6e90b755 *man/faasr_acquire.Rd
d1d9feacfda727d116334998545d4327 *man/faasr_anyone_else_interested.Rd
0165fa1f58872f42f26a223945a4d7ca *man/faasr_arrow_s3_bucket.Rd
23734fe537a27d1fc150458fbaf2d01b *man/faasr_check_workflow_cycle.Rd
d23396786d9194508f26a0e075cbfab7 *man/faasr_collect_sys_env.Rd
e9994e23a4cfb4d7bf7e209a13ac42e2 *man/faasr_delete_file.Rd
63e073e465bf6336970275ec084e301a *man/faasr_get_file.Rd
1726971bbc0383a9982ce4b7baa1b6be *man/faasr_get_user_function_args.Rd
fbd154aeb83908030d8f158d00b48ff9 *man/faasr_httr_request.Rd
4807ea82d27290bf494fc565b523df41 *man/faasr_init_log_folder.Rd
e5d3f794bcd3bd1f60c40df5c811f30d *man/faasr_invoke_workflow.Rd
d96854095a5dc5654a33548a0d4bc2f6 *man/faasr_lock.Rd
fa5db1475747b5a1c2d92ee7f26a3006 *man/faasr_log.Rd
b8d935abe0a013a628e56ecaf0a5c131 *man/faasr_ow_httr_request.Rd
62a9c40b71698de8633cfc02aa8490ce *man/faasr_parse.Rd
cf81c9dca728285660f9fa41faf3ffca *man/faasr_predecessors_list.Rd
32db513611f3a5c64993bd8472552e51 *man/faasr_put_file.Rd
2abb11fc5cf12567807eef3c1d0d87af *man/faasr_register_workflow.Rd
e8ff9540aa304c7ff6f2b805211e3541 *man/faasr_register_workflow_aws_lambda.Rd
8ae28ecff6348d7ed0f2f62449c195f7 *man/faasr_register_workflow_aws_lambda_function_build.Rd
d248032a5035c79864d431ea1a7e28a5 *man/faasr_register_workflow_aws_lambda_role_create.Rd
6faaa5276582f283cbdb27ee7aa72cb4 *man/faasr_register_workflow_git_local_repo.Rd
68b2e6e04a44221e1a557a80f21a6aa9 *man/faasr_register_workflow_git_remote_env.Rd
acbadf2ab39c16c9c85099742e59ceba *man/faasr_register_workflow_git_remote_repo.Rd
3165eaae2465b252bc4ab70157d332cc *man/faasr_register_workflow_github_actions.Rd
1c5fdec6abaaba81f323650c96b23db2 *man/faasr_register_workflow_github_create_dir.Rd
40998fb3e3eac59f6eb9ff69597ae593 *man/faasr_register_workflow_github_create_env.Rd
c3af8cfe7d3ae07b250618be6ee4566d *man/faasr_register_workflow_github_create_payload.Rd
072cf38ed68b713a7b72e2743718f1f8 *man/faasr_register_workflow_github_create_readme.Rd
8237f6c37cbb8a028ac02168b10f142b *man/faasr_register_workflow_github_create_yml_file.Rd
91da05373256a258d5773f02856dd881 *man/faasr_register_workflow_github_repo_exists.Rd
1d838a28161955897539412754ee6761 *man/faasr_register_workflow_github_repo_lists.Rd
459275431d86e5af4bfa5965ab665775 *man/faasr_register_workflow_github_repo_question.Rd
3f8752d64ca75207479706c646dcaccb *man/faasr_register_workflow_lambda_function_image.Rd
b2971b567cd6a885821b5006e7877aef *man/faasr_register_workflow_lambda_function_info.Rd
4eb3fd5d4e9c49b8b3b00fb04d740659 *man/faasr_register_workflow_lambda_function_lists.Rd
7c71014ec4de24f3e6f31f1b51dac76e *man/faasr_register_workflow_lambda_server_info.Rd
155a2664f3cb4b92144a045f034c3389 *man/faasr_register_workflow_openwhisk.Rd
be13f7cb6bca4bea9ce48edb6578fce3 *man/faasr_register_workflow_openwhisk_action_lists.Rd
02ffce8756ce948ae42d4427b0f1ff19 *man/faasr_register_workflow_openwhisk_check_exists.Rd
fa8b4f24e7fa0ef2274d41ca7b658bfd *man/faasr_register_workflow_openwhisk_check_user_input.Rd
75ee2ce3b7b63bb74ba75a0b4e81793f *man/faasr_register_workflow_openwhisk_create_action.Rd
e4d5f9762aaa06330e44aeb7c6ea1e4b *man/faasr_release.Rd
05c4cae812b0acc40589485b962ce5de *man/faasr_replace_values.Rd
06bea8de7955a535945a4ce15d6dfe97 *man/faasr_run_user_function.Rd
9597c7f22d12713b698b9e4dcec6506c *man/faasr_s3_check.Rd
3a89bb509e2a6caec227aa531a0a4d3c *man/faasr_set_workflow_timer.Rd
8c14d493c82922321b403c34d26adb12 *man/faasr_set_workflow_timer_gh.Rd
16af7571fcb3685bc5fcb2dea7566034 *man/faasr_set_workflow_timer_ld.Rd
78f6757a1f5d72dd35106e83b38fc3ec *man/faasr_set_workflow_timer_ow.Rd
f724aa65ea1d8c9ee95019997decb1dd *man/faasr_start.Rd
bc3dab96aaae3973270bf751df46aeb2 *man/faasr_trigger.Rd
2d3ccb9b1aeabc53729d48825ccd6111 *man/faasr_unset_workflow_timer.Rd
ce01faeee3068edf32e3fd5906cbd913 *man/faasr_workflow_invoke_github.Rd
3ddb9ba8c75bab01243e2af3604d76b5 *man/faasr_workflow_invoke_lambda.Rd
3c593fd0f60b6c88c784bada818fcb28 *man/faasr_workflow_invoke_openwhisk.Rd
f2b6398c5e190195daacf8190a64d331 *tests/testthat.R
d654e570069fc3542003a893d0e90f64 *tests/testthat/test-faasr.R
b827ce351e8971a85b86e80b7dd630bc *tests/testthat/test-faasr_check_workflow_cycle.R
fce1d752a82eff756705ef3a3c211661 *tests/testthat/test-faasr_collect_sys_env.R
02bc554b4a47f60ab0d467f032937915 *tests/testthat/test-faasr_get_user_function_args.R
b29e7cd4133b78374c55a89d90612434 *tests/testthat/test-faasr_parse.R
fdd2c0cd2dbc95554d1c03a92f59f246 *tests/testthat/test-faasr_predecessor_list.R
c1b5031bb6745b09ad0c96880ad592cc *tests/testthat/test-faasr_register_workflow_github_repo_lists.R
ff5bb16bb2896d7d2d53075129b2d9a3 *tests/testthat/test-faasr_register_workflow_openwhisk_action_lists.R
0367d74cc3a3de6b8a3efc430b9d56e7 *tests/testthat/test-faasr_replace_values.R
71d8a50dbf87ad1a7781036287e532ec *tests/testthat/test.json
32 changes: 32 additions & 0 deletions NAMESPACE
@@ -0,0 +1,32 @@
# Generated by roxygen2: do not edit by hand

export(faasr)
export(faasr_arrow_s3_bucket)
export(faasr_delete_file)
export(faasr_get_file)
export(faasr_invoke_workflow)
export(faasr_log)
export(faasr_parse)
export(faasr_put_file)
export(faasr_register_workflow)
export(faasr_replace_values)
export(faasr_run_user_function)
export(faasr_set_workflow_timer)
export(faasr_start)
export(faasr_trigger)
export(faasr_unset_workflow_timer)
import(cli)
import(httr)
import(jsonlite)
import(jsonvalidate)
import(uuid)
importFrom("base64enc","base64decode")
importFrom("base64enc","base64encode")
importFrom("paws.application.integration","eventbridge")
importFrom("paws.compute","ecr")
importFrom("paws.compute","lambda")
importFrom("paws.security.identity","iam")
importFrom("paws.security.identity","sts")
importFrom("paws.storage","s3")
importFrom("sodium","simple_encrypt")
importFrom("utils","write.table")
7 changes: 7 additions & 0 deletions NEWS.md
@@ -0,0 +1,7 @@
# FaaSr 1.1.2

* This version incorporates CRAN review feedback from initial submission

# FaaSr 1.1.1

* CRAN New Submission
123 changes: 123 additions & 0 deletions R/faasr_abort_on_multiple_invocations.R
@@ -0,0 +1,123 @@
#' @name faasr_abort_on_multiple_invocations
#' @title faasr_abort_on_multiple_invocations
#' @description
#' Ensures that only one Action proceeds to execute a User Function if there are multiple triggers
#' This is necessary because if in the Workflow a function receives multiple triggers,
#' multiple Actions are invoked; however, we don't want to execute the same function multiple times.
#' This function aborts all but the last Action triggered.
#' @param faasr list with parsed and validated Payload
#' @param pre list with names of functions and corresponding predecessors
#' @keywords internal
#' @import uuid
#' @importFrom "paws.storage" "s3"

faasr_abort_on_multiple_invocations <- function(faasr, pre) {

# Set env for checking
if (is.null(faasr$LoggingDataStore)){
log_server_name = faasr$DefaultDataStore
} else {
log_server_name = faasr$LoggingDataStore
}

if (log_server_name %in% names(faasr$DataStores)) {
NULL
} else {
err_msg <- paste0('{\"faasr_abort_on_multiple_invocation\":\"Invalid data server name: ',log_server_name,'\"}', "\n")
message(err_msg)
stop()
}

log_server <- faasr$DataStores[[log_server_name]]
s3<-paws.storage::s3(
config=list(
credentials=list(
creds=list(
access_key_id=log_server$AccessKey,
secret_access_key=log_server$SecretKey
)
),
endpoint=log_server$Endpoint,
region=log_server$Region
)
)

id_folder <- paste0(faasr$FaaSrLog,"/",faasr$InvocationID)

# Step 1: First, we check if all possible predecessor Actions are marked "done"
# This is done by checking if a file named "func.done" exists in S3, where func is the name of the predecessor
# If all possible predecessors are "done", we continue to step 2: below to check which of those should execute
# If not all predecessors are done, it means there are still predecessors pending, and it's safe for this one to abort

check_fn_done<-s3$list_objects_v2(Bucket=log_server$Bucket, Prefix=id_folder)
check_fn_done_list <- lapply(check_fn_done$Contents, function(x) x$Key)

for (func in pre) {
# check filename is "functionname.done"
func_done <- paste0(id_folder,"/",func,".done")
# if object exists, do nothing.
# if object doesn't exist, leave a log that this function should wait and will be discarded
if (!func_done %in% check_fn_done_list){
res_msg <- paste0('{\"faasr_abort_on_multiple_invocations\":\"not the last trigger invoked - no flag\"}', "\n")
message(res_msg)
faasr_log(res_msg)
stop()
}
}

# generate random number to be appended to a file named "$FunctionInvoke.candidate"
random_number <- sample(1:10000000, 1)

# Check whether local directory exists, if not, create one.
if (!dir.exists(id_folder)) {
dir.create(id_folder, recursive=TRUE)
}

func_candidate <- paste0(id_folder,"/",faasr$FunctionInvoke,".candidate")

# Step 2: This code is reached only if all predecessors are done. Now we need to select only one Action to proceed,
# while all other Actions should abort
# The code region below uses a lock implementation over S3 to implement read/modify/write and avoid a race condition
# Between lock acquire and release, we do the following:
# 1) download the "$FunctionInvoke.candidate" file from S3. The candidate file stores random numbers generated by
# each Actions which have been invoked for this function after all predecessors are done.
# 2) append a random number to the local file, which is generated by this Action
# 3) upload the file back to the S3 bucket
# 4) download the file from S3
# acquire a Lock
faasr_acquire(faasr)

# if file named "$FunctionInvoke.candidate" exists on the S3 server, download it to the local folder
check_fn_candidate <- s3$list_objects_v2(Bucket=log_server$Bucket, Prefix=func_candidate)
if (length(check_fn_candidate$Contents) != 0) {
if (file.exists(func_candidate)) {
file.remove(func_candidate)
}
s3$download_file(Key=func_candidate, Filename=func_candidate, Bucket=log_server$Bucket)
}

# append random number to the file, and upload it back to the s3 bucket
write.table(random_number, func_candidate, col.names=FALSE, row.names = FALSE, append=TRUE, quote=FALSE)
result <- s3$put_object(Body=func_candidate, Key=func_candidate, Bucket=log_server$Bucket)

# download from the S3 server to the local folder, again
if (file.exists(func_candidate)) {
file.remove(func_candidate)
}
s3$download_file(Key=func_candidate, Filename=func_candidate, Bucket=log_server$Bucket)

# release the Lock
faasr_release(faasr)

# if the first line of the candidate file matches the random number generated by this action,
# this action is the only one that won't abort
# essentially, the first action to append to the candidate file proceeds; all others will abort
if (as.character(random_number) == readLines(func_candidate,1)) {
NULL
} else {
res_msg <- paste0('{\"faasr_abort_on_multiple_invocations\":\"not the last trigger invoked - random number does not match\"}', "\n")
message(res_msg)
faasr_log(res_msg)
stop()
}
}
41 changes: 41 additions & 0 deletions R/faasr_arrow_s3_bucket.R
@@ -0,0 +1,41 @@
#' @name faasr_arrow_s3_bucket
#' @title faasr_arrow_s3_bucket
#' @description
#' `test` Uses "arrow" library to set up the configurations with given json file and
#' provide the object to the users
#' @param server_name for string, default value is faasr$DefaultDataStore
#' @return s3 representing object for "arrow"
#' @export
#' @examples
#' # this function can be run only inside the container
#' if (interactive()){
#' arrow_s3 <- faasr_arrow_s3_bucket()
#' arrow_s3$ls
#' }

globalVariables(".faasr")

faasr_arrow_s3_bucket <- function(server_name=.faasr$DefaultDataStore) {
# Check that an S3 server_name has been defined
# If not, log an error and abort

if (server_name %in% names(.faasr$DataStores)) {
NULL
} else {
err_msg <- paste0('{\"faasr_get_arrow\":\"Invalid data server name: ',server_name,'\"}', "\n")
message(err_msg)
stop()
}

target_s3 <- .faasr$DataStores[[server_name]]


s3 <- arrow::s3_bucket(
bucket = target_s3$Bucket,
access_key = target_s3$AccessKey,
secret_key = target_s3$SecretKey,
endpoint_override = target_s3$Endpoint
)

return(s3)
}

0 comments on commit 41a2cb8

Please sign in to comment.