galaaz 0.5.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +46 -0
- data/LICENSE +0 -0
- data/README.md +1416 -667
- data/Rakefile +68 -41
- data/bin/galaaz-bootstrap +137 -0
- data/bin/galaaz-jruby +11 -0
- data/bin/galaaz-ruby +16 -0
- data/bin/galaaz_jruby_env.inc.sh +6 -0
- data/bin/galaaz_ruby_env.inc.sh +36 -0
- data/bin/gbookdown +63 -0
- data/bin/gknit +83 -13
- data/bin/gknit-draft.rb +0 -0
- data/bin/gstudio +5 -3
- data/bin/gstudio_irb.rb +0 -0
- data/bin/gstudio_pry.rb +0 -0
- data/bin/install-tinytex +6 -0
- data/bin/run_all_rspec +44 -0
- data/bin/run_example +17 -0
- data/bin/run_old_rspec +20 -0
- data/bin/run_rspec +24 -0
- data/bin/run_rspec_subset +38 -0
- data/bin/run_slow_rspec +20 -0
- data/blogs/R-on-Rails-Planning-Document.md +940 -0
- data/blogs/README.md +100 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.Rmd +38 -66
- data/blogs/galaaz_ggplot/galaaz_ggplot.log +754 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot.md +115 -155
- data/blogs/galaaz_ggplot/galaaz_ggplot.tex +607 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-gfm/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-gfm/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-html/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/midwest_rb.png +0 -0
- data/blogs/galaaz_ggplot/galaaz_ggplot_files/figure-markdown_github/scatter_plot_rb.png +0 -0
- data/blogs/galaaz_ggplot/midwest.Rmd +3 -3
- data/blogs/galaaz_ggplot/midwest_external_png +0 -0
- data/blogs/gknit/gknit.Rmd +47 -52
- data/blogs/gknit/gknit.md +1430 -0
- data/blogs/gknit/gknit_files/figure-gfm/bubble-1.png +0 -0
- data/blogs/gknit/gknit_files/figure-gfm/diverging_bar.png +0 -0
- data/blogs/gknit/gknit_files/figure-html/bubble-1.png +0 -0
- data/blogs/gknit/gknit_files/figure-html/diverging_bar.png +0 -0
- data/blogs/gknit/lst.rds +0 -0
- data/blogs/gknit/model.rb +1 -1
- data/blogs/gknit/stats.bib +0 -0
- data/blogs/manual/include_model_local_repro.Rmd +14 -0
- data/blogs/manual/include_model_local_repro.md +75 -0
- data/blogs/manual/lst.rds +0 -0
- data/blogs/manual/manual.Rmd +855 -239
- data/blogs/manual/manual.log +1786 -0
- data/blogs/manual/manual.md +1416 -667
- data/blogs/manual/manual.tex +1883 -1161
- data/blogs/manual/manual_files/figure-html/bubble-1.png +0 -0
- data/blogs/manual/manual_files/figure-html/diverging_bar.png +0 -0
- data/blogs/manual/manual_files/figure-latex/bubble-1.png +0 -0
- data/blogs/manual/model.rb +1 -1
- data/blogs/nse_dplyr/nse_dplyr.Rmd +84 -111
- data/blogs/nse_dplyr/nse_dplyr.log +928 -0
- data/blogs/nse_dplyr/nse_dplyr.md +198 -229
- data/blogs/oh_my/not_so.rb +0 -0
- data/blogs/oh_my/oh_my.Rmd +1234 -25
- data/blogs/oh_my/oh_my.log +804 -0
- data/blogs/oh_my/oh_my.md +1663 -86
- data/blogs/oh_my/oh_my.tex +821 -0
- data/blogs/oh_my/old.Rmd +15 -14
- data/blogs/ruby_plot/ruby_plot.Rmd +58 -82
- data/blogs/ruby_plot/ruby_plot.log +885 -0
- data/blogs/ruby_plot/ruby_plot.md +71 -102
- data/blogs/ruby_plot/ruby_plot.tex +940 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-gfm/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-html/violin_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/dose_len.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_delivery.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facet_by_dose.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_by_delivery_color2.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_decorations.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_jitter.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/facets_with_points.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_box_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/final_violin_plot.png +0 -0
- data/blogs/ruby_plot/ruby_plot_files/figure-latex/violin_with_jitter.png +0 -0
- data/blogs/test/test.Rmd +14 -0
- data/blogs/test/test.md +10 -0
- data/examples/50Plots_MasterList/Images/midwest-scatterplot.PNG +0 -0
- data/examples/50Plots_MasterList/ScatterPlot.rb +2 -1
- data/examples/50Plots_MasterList/scatter_plot.rb +1 -0
- data/examples/Bibliography/master.bib +0 -0
- data/examples/Bibliography/stats.bib +0 -0
- data/examples/R/calc.R +0 -0
- data/examples/R/java_interop.R +0 -0
- data/examples/bioconductor_deseq2_airway/Documentation/DESeq2-airway-walkthrough.md +56 -0
- data/examples/bioconductor_deseq2_airway/bench_galaaz_three_same_process.rb +54 -0
- data/examples/bioconductor_deseq2_airway/bench_r_three_same_process.R +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz.rb +34 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_galaaz_optimized.rb +35 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_minimal.R +30 -0
- data/examples/bioconductor_deseq2_airway/deseq2_airway_pipeline_for_bench.R +36 -0
- data/examples/islr/all.rb +14 -0
- data/examples/islr/ch2.spec.rb +38 -7
- data/examples/islr/ch3.spec.rb +12 -2
- data/examples/islr/ch3_boston.rb +28 -0
- data/examples/islr/ch3_multiple_regression.rb +1 -0
- data/examples/islr/ch6.spec.rb +25 -1
- data/examples/islr/x_y_rnorm.jpg +0 -0
- data/examples/latex_templates/Test-acm_article/acm_proc_article-sp.cls +0 -0
- data/examples/latex_templates/Test-acm_article/sigproc.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-Test-acs_article.bib +0 -0
- data/examples/latex_templates/Test-acs_article/acs-my_output.bib +0 -0
- data/examples/latex_templates/Test-aea_article/BibFile.bib +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.Rmd +0 -0
- data/examples/latex_templates/Test-aea_article/references.bib +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.Rmd +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdfsync +0 -0
- data/examples/latex_templates/Test-ieee_article/IEEEtran.bst +0 -0
- data/examples/latex_templates/Test-ieee_article/mybibfile.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJournal.sty +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJreferences.bib +0 -0
- data/examples/latex_templates/Test-rjournal_article/Test-rjournal_article.Rmd +0 -0
- data/examples/misc/baseball.csv +0 -0
- data/examples/misc/ggplot.rb +5 -3
- data/examples/misc/moneyball.rb +1 -0
- data/examples/misc/subsetting.rb +1 -0
- data/examples/multithread_shards_to_r/shards_to_r.rb +68 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.Rmd +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/attend-grade-relationships.csv +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.Rmd +0 -0
- data/examples/rmarkdown/svm-xaringan-example/svm-xaringan-example.Rmd +0 -0
- data/examples/sthda_ggplot/README.md +0 -0
- data/examples/sthda_ggplot/RUN.md +41 -0
- data/examples/sthda_ggplot/all.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/density_gg.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_area.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_density.rb +3 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_dotplot.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_freqpoly.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/geom_histogram.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/histogram_density.rb +1 -0
- data/examples/sthda_ggplot/one_variable_continuous/stat.rb +1 -0
- data/examples/sthda_ggplot/one_variable_discrete/bar.rb +1 -0
- data/examples/sthda_ggplot/qplots/box_violin_dot.rb +1 -0
- data/examples/sthda_ggplot/qplots/scatter_plots.rb +1 -0
- data/examples/sthda_ggplot/scatter_gg.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_bin2d.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_density2d.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_bivariate/geom_hex.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_point.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/geom_smooth.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_cont/misc.rb +1 -0
- data/examples/sthda_ggplot/two_variables_cont_function/geom_area.rb +5 -3
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_bar.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_boxplot.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_dotplot.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_jitter.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_line.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_cont/geom_violin.rb +1 -0
- data/examples/sthda_ggplot/two_variables_disc_disc/geom_jitter.rb +1 -0
- data/examples/sthda_ggplot/two_variables_error/geom_crossbar.rb +1 -0
- data/ext/new_bridge/Makefile +46 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase0.cpp +12 -0
- data/ext/new_bridge/galaaz_gatekeeper_phase1.cpp +1639 -0
- data/lib/R_interface/galaaz_device.R +20 -0
- data/lib/R_interface/include_engine.R +109 -0
- data/lib/R_interface/new_bridge_adapter.rb +824 -0
- data/lib/R_interface/r.rb +177 -25
- data/lib/R_interface/r_arrow.rb +113 -0
- data/lib/R_interface/r_libs.R +3 -3
- data/lib/R_interface/r_methods.rb +13 -126
- data/lib/R_interface/r_module_s.rb +0 -0
- data/lib/R_interface/rbinary_operators.rb +20 -2
- data/lib/R_interface/rclosure.rb +5 -1
- data/lib/R_interface/rdata_frame.rb +34 -70
- data/lib/R_interface/rdevice.rb +125 -0
- data/lib/R_interface/rdevices.R +0 -0
- data/lib/R_interface/renvironment.rb +10 -4
- data/lib/R_interface/rexpression.rb +5 -1
- data/lib/R_interface/rindexed_object.rb +41 -13
- data/lib/R_interface/rlanguage.rb +20 -62
- data/lib/R_interface/rlist.rb +115 -25
- data/lib/R_interface/rlogical_operators.rb +0 -0
- data/lib/R_interface/rmatrix.rb +2 -11
- data/lib/R_interface/rmd_indexed_object.rb +5 -1
- data/lib/R_interface/robject.rb +348 -290
- data/lib/R_interface/rpkg.rb +0 -0
- data/lib/R_interface/rsupport.rb +609 -328
- data/lib/R_interface/rsupport_scope.rb +2 -1
- data/lib/R_interface/rsymbol.rb +50 -0
- data/lib/R_interface/ruby_callback.rb +2 -3
- data/lib/R_interface/ruby_extensions.rb +225 -175
- data/lib/R_interface/runary_operators.rb +0 -0
- data/lib/R_interface/rvector.rb +162 -31
- data/lib/galaaz.rb +0 -0
- data/lib/galaaz_jruby.rb +22 -0
- data/lib/galaaz_ruby.rb +34 -0
- data/lib/gknit/diagnostics.rb +50 -0
- data/lib/gknit/draft.rb +23 -17
- data/lib/gknit/include_engine.rb +15 -7
- data/lib/gknit/knitr_engine.rb +223 -74
- data/lib/gknit/rb_engine.rb +3 -3
- data/lib/gknit/ruby_engine.rb +0 -0
- data/lib/gknit.rb +1 -0
- data/lib/new_bridge/bootstrap/windows_bootstrap.rb +285 -0
- data/lib/new_bridge/envelope.rb +51 -0
- data/lib/new_bridge/eval_result.rb +26 -0
- data/lib/new_bridge/framing.rb +39 -0
- data/lib/new_bridge/instance_pool_client.rb +38 -0
- data/lib/new_bridge/r_instance_manager.rb +404 -0
- data/lib/new_bridge/session_client.rb +530 -0
- data/lib/new_bridge/tcp_framed.rb +44 -0
- data/lib/new_bridge.rb +9 -0
- data/lib/util/exec_ruby.rb +95 -20
- data/lib/util/inline_file.rb +35 -30
- data/new_bridge_specs/benchmark_phase5_5_unboxing_spec.rb +96 -0
- data/new_bridge_specs/eval_r_async_spec.rb +113 -0
- data/new_bridge_specs/integration_phase5_1_concurrent_spec.rb +50 -0
- data/new_bridge_specs/integration_phase5_1_eval_spec.rb +16 -0
- data/new_bridge_specs/integration_phase5_1_r_api_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_1_smoke_spec.rb +31 -0
- data/new_bridge_specs/integration_phase5_2_dataframe_unboxing_spec.rb +19 -0
- data/new_bridge_specs/integration_phase5_2_handle_eval_unboxing_spec.rb +25 -0
- data/new_bridge_specs/integration_phase5_3_callback_args_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callback_error_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_callback_timeout_spec.rb +28 -0
- data/new_bridge_specs/integration_phase5_3_callbacks_smoke_spec.rb +22 -0
- data/new_bridge_specs/integration_phase5_3_edge_cases_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_3_nested_spec.rb +30 -0
- data/new_bridge_specs/integration_phase5_4_concurrent_sessions_spec.rb +53 -0
- data/new_bridge_specs/integration_phase5_4_nested_session_callbacks_spec.rb +49 -0
- data/new_bridge_specs/integration_phase5_4_session_routing_spec.rb +38 -0
- data/new_bridge_specs/integration_phase5_5_stress_concurrency_spec.rb +52 -0
- data/new_bridge_specs/integration_phase5_5_unbox_walk_spec.rb +46 -0
- data/new_bridge_specs/phase0_protocol_spec.rb +96 -0
- data/new_bridge_specs/phase1_req_ret_spec.rb +66 -0
- data/new_bridge_specs/phase2_multi_instance_spec.rb +67 -0
- data/new_bridge_specs/phase3_callbacks_spec.rb +71 -0
- data/new_bridge_specs/phase4_2_hardening_spec.rb +252 -0
- data/new_bridge_specs/phase4_3_r_instance_manager_spec.rb +85 -0
- data/new_bridge_specs/phase4_nested_callbacks_spec.rb +123 -0
- data/r_requires/ggplot.rb +0 -0
- data/r_requires/knitr.rb +0 -0
- data/specs/all.rb +15 -11
- data/specs/arrow_from_ruby_batches_spec.rb +50 -0
- data/specs/arrow_semantics_spec.rb +64 -0
- data/specs/bridge_concurrent_spec.rb +46 -0
- data/specs/bridge_nested_spec.rb +25 -0
- data/specs/dataframe_semantics_spec.rb +122 -0
- data/specs/dataframe_single_index_logical_filter_spec.rb +21 -0
- data/specs/dispatch_probe_cache_spec.rb +38 -0
- data/specs/dispatch_probe_error_class_fallback_spec.rb +20 -0
- data/specs/dispatch_probe_fallback_spec.rb +18 -0
- data/specs/environment_semantics_spec.rb +89 -0
- data/specs/field_access_spec.rb +31 -0
- data/specs/figures/bg.jpeg +0 -0
- data/specs/figures/bg.png +0 -0
- data/specs/figures/bg.svg +168 -57
- data/specs/figures/dose_len.png +0 -0
- data/specs/figures/no_args.jpeg +0 -0
- data/specs/figures/no_args.png +0 -0
- data/specs/figures/no_args.svg +168 -57
- data/specs/figures/width_height.jpeg +0 -0
- data/specs/figures/width_height.png +0 -0
- data/specs/figures/width_height_units1.jpeg +0 -0
- data/specs/figures/width_height_units1.png +0 -0
- data/specs/figures/width_height_units2.jpeg +0 -0
- data/specs/figures/width_height_units2.png +0 -0
- data/specs/formula_semantics_spec.rb +81 -0
- data/specs/galaaz_util_exec_ruby_spec.rb +85 -0
- data/specs/galaaz_util_inline_file_spec.rb +54 -0
- data/specs/gknit_cli_option_permutation_spec.rb +24 -0
- data/specs/gknit_include_engine_spec.rb +72 -0
- data/specs/gknit_install_timeout_report_spec.rb +69 -0
- data/specs/gknit_internal_error_report_spec.rb +57 -0
- data/specs/gknit_vector_map_output_spec.rb +59 -0
- data/specs/globalenv_guardrail_spec.rb +52 -0
- data/specs/language_expression_semantics_spec.rb +145 -0
- data/specs/list_semantics_spec.rb +111 -0
- data/specs/new_bridge_bulk_dataframe_transfer_spec.rb +44 -0
- data/specs/new_bridge_bulk_vector_transfer_spec.rb +73 -0
- data/specs/new_bridge_callback_timeout_spec.rb +69 -0
- data/specs/new_bridge_eval_r_fallback_spec.rb +55 -0
- data/specs/nil_null_spec.rb +42 -0
- data/specs/object_build_phase2_spec.rb +53 -0
- data/specs/phase1_callback_bridge_spec.rb +84 -0
- data/specs/phase2_gknit_generic_rendering_guardrail_spec.rb +46 -0
- data/specs/phase2_gknit_no_raw_code_leakage_spec.rb +43 -0
- data/specs/phase3_gknit_generic_graphics_capture_spec.rb +71 -0
- data/specs/plot_device_semantics_spec.rb +28 -0
- data/specs/plot_snapshot_semantics_spec.rb +58 -0
- data/specs/protocol_result_spec.rb +236 -0
- data/specs/r_batch_fail_fast_spec.rb +47 -0
- data/specs/r_bridge_bootstrap_spec.rb +11 -0
- data/specs/r_devices.spec.rb +1 -1
- data/specs/r_eval.spec.rb +16 -18
- data/specs/r_function.spec.rb +1 -1
- data/specs/r_instance_manager_spec.rb +285 -0
- data/specs/r_list_apply.spec.rb +15 -15
- data/specs/r_matrix.spec.rb +0 -0
- data/specs/r_nse.spec.rb +5 -5
- data/specs/r_object_send_dispatch_spec.rb +13 -0
- data/specs/r_vector_comparator_spec.rb +8 -0
- data/specs/r_vector_creation.spec.rb +0 -0
- data/specs/r_vector_functions.spec.rb +0 -0
- data/specs/r_vector_object.spec.rb +0 -0
- data/specs/r_vector_operators.spec.rb +0 -0
- data/specs/r_vector_structured_scalar_reads_spec.rb +35 -0
- data/specs/r_vector_subsetting.spec.rb +0 -0
- data/specs/range_helper_spec.rb +21 -0
- data/specs/rsupport_scope_spec.rb +28 -0
- data/specs/rsupport_var_name_thread_safety_spec.rb +24 -0
- data/specs/scalar_character_spec.rb +44 -0
- data/specs/scoped_symbol_dsl_refinement_spec.rb +40 -0
- data/specs/session_env_bridge_spec.rb +25 -0
- data/specs/simplecov_bootstrap_spec.rb +10 -0
- data/specs/spec_helper.rb +10 -0
- data/specs/tmp.rb +0 -0
- data/specs/unboxing_recursion_regression_spec.rb +30 -0
- data/specs/unboxing_spec.rb +49 -0
- data/specs/verify_callbacks.rb +42 -0
- data/sty/galaaz.sty +0 -0
- data/version.rb +1 -1
- metadata +219 -63
- data/blogs/galaaz_ggplot/galaaz_ggplot.html +0 -520
- data/blogs/galaaz_ggplot/galaaz_ggplot.pdf +0 -0
- data/blogs/galaaz_ggplot/midwest.html +0 -188
- data/blogs/gknit/gknit.html +0 -2266
- data/blogs/gknit/gknit.pdf +0 -0
- data/blogs/manual/manual.html +0 -4638
- data/blogs/manual/manual.pdf +0 -0
- data/blogs/manual/manual_files/figure-latex/diverging_bar.pdf +0 -0
- data/blogs/nse_dplyr/nse_dplyr.html +0 -878
- data/blogs/nse_dplyr/nse_dplyr.pdf +0 -0
- data/blogs/oh_my/oh_my.html +0 -568
- data/blogs/ruby_plot/ruby_plot.html +0 -544
- data/blogs/ruby_plot/ruby_plot.pdf +0 -0
- data/examples/latex_templates/Test-acs_article/Test-acs_article.pdf +0 -0
- data/examples/latex_templates/Test-aea_article/Test-aea_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/Test-amq_article.pdf +0 -0
- data/examples/latex_templates/Test-amq_article/pics/Figure2.pdf +0 -0
- data/examples/latex_templates/Test-asa_article/Test-asa_article.pdf +0 -0
- data/examples/latex_templates/Test-ieee_article/Test-ieee_article.pdf +0 -0
- data/examples/latex_templates/Test-rjournal_article/RJwrapper.pdf +0 -0
- data/examples/latex_templates/Test-springer_article/Test-springer_article.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-anon-ms-example/svm-rmarkdown-anon-ms-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-article-example/svm-rmarkdown-article-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-beamer-example/svm-rmarkdown-beamer-example.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-cv/svm-rmarkdown-cv.pdf +0 -0
- data/examples/rmarkdown/svm-rmarkdown-syllabus-example/svm-rmarkdown-syllabus-example.pdf +0 -0
- data/specs/r_dataframe.spec.rb +0 -379
- data/specs/r_environment.spec.rb +0 -140
- data/specs/r_formula.spec.rb +0 -232
- data/specs/r_language.spec.rb +0 -112
- data/specs/r_list.spec.rb +0 -293
- data/specs/r_plots.spec.rb +0 -72
- data/specs/ruby_expression.spec.rb +0 -316
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'open3'
|
|
4
|
+
|
|
5
|
+
module NewBridge
|
|
6
|
+
module Bootstrap
|
|
7
|
+
# Windows-first bootstrap executed from WSL.
|
|
8
|
+
# Supports:
|
|
9
|
+
# - --check: diagnostics only
|
|
10
|
+
# - --apply: apply WSL-side fixes when possible
|
|
11
|
+
class WindowsBootstrap
|
|
12
|
+
attr_reader :checks, :actions
|
|
13
|
+
|
|
14
|
+
def initialize(out: $stdout, err: $stderr, command_runner: nil, env: ENV, wsl_override: nil)
|
|
15
|
+
@out = out
|
|
16
|
+
@err = err
|
|
17
|
+
@runner = command_runner || method(:default_runner)
|
|
18
|
+
@env = env
|
|
19
|
+
@wsl_override = wsl_override
|
|
20
|
+
@checks = []
|
|
21
|
+
@actions = []
|
|
22
|
+
@selected_runtime_mode = :docker
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def run(mode: :check, runtime_mode: :docker)
|
|
26
|
+
unless %i[check apply].include?(mode)
|
|
27
|
+
raise ArgumentError, "invalid mode=#{mode} (expected :check or :apply)"
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
@selected_runtime_mode = resolve_runtime_mode(runtime_mode)
|
|
31
|
+
header(mode)
|
|
32
|
+
evaluate_checks
|
|
33
|
+
|
|
34
|
+
if mode == :apply
|
|
35
|
+
apply_fixes_for_selected_runtime
|
|
36
|
+
evaluate_checks(reset: true)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
summary(mode)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def header(mode)
|
|
45
|
+
@out.puts "Galaaz bootstrap (windows/wsl) - mode=#{mode}, runtime=#{@selected_runtime_mode}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def evaluate_checks(reset: false)
|
|
49
|
+
@checks.clear if reset
|
|
50
|
+
add_check('wsl', wsl?, 'WSL2 environment available')
|
|
51
|
+
add_check('docker_cli', command_exists?('docker'), 'docker CLI available in WSL')
|
|
52
|
+
add_check('docker_daemon', docker_daemon_ok?, 'docker daemon reachable from WSL')
|
|
53
|
+
add_check('docker_compose', docker_compose_ok?, 'docker compose plugin available')
|
|
54
|
+
add_check('ruby', command_exists?('ruby'), 'ruby available')
|
|
55
|
+
add_check('r', command_exists?('R'), 'R available')
|
|
56
|
+
add_check('rcpp', rcpp_ok?, 'Rcpp package available')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def add_check(name, ok, message)
|
|
60
|
+
@checks << { name: name, ok: ok, message: message }
|
|
61
|
+
@out.puts format("%-16s %s - %s", name, ok ? 'PASS' : 'FAIL', message)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def apply_fixes_for_selected_runtime
|
|
65
|
+
if @selected_runtime_mode == :local
|
|
66
|
+
apply_local_runtime_fixes
|
|
67
|
+
else
|
|
68
|
+
apply_wsl_docker_fixes
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def apply_wsl_docker_fixes
|
|
73
|
+
@out.puts 'Applying WSL-side fixes where possible...'
|
|
74
|
+
|
|
75
|
+
unless wsl?
|
|
76
|
+
@actions << 'not_wsl_skip_apply'
|
|
77
|
+
@out.puts 'SKIP: apply mode is intended for WSL environments.'
|
|
78
|
+
return
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
unless command_exists?('docker')
|
|
82
|
+
install_docker_in_wsl
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
if command_exists?('docker') && !docker_compose_ok?
|
|
86
|
+
install_docker_compose_plugin
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
if command_exists?('docker') && !docker_daemon_ok?
|
|
90
|
+
@actions << 'manual_docker_desktop_integration_required'
|
|
91
|
+
@out.puts 'MANUAL: Docker daemon is not reachable. If using Docker Desktop, enable WSL integration for this distro.'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def apply_local_runtime_fixes
|
|
96
|
+
@out.puts 'Applying local-runtime fixes (R in WSL)...'
|
|
97
|
+
@actions << 'install_local_r_wsl'
|
|
98
|
+
run_ok('sudo apt-get update')
|
|
99
|
+
run_ok('sudo apt-get install -y r-base r-base-dev')
|
|
100
|
+
run_ok(%q{Rscript -e "if(!requireNamespace('Rcpp', quietly=TRUE)) install.packages('Rcpp', repos='https://cloud.r-project.org/')"})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def install_docker_in_wsl
|
|
104
|
+
@out.puts 'Attempting docker install in WSL (apt)...'
|
|
105
|
+
@actions << 'install_docker_wsl'
|
|
106
|
+
ok = run_ok('sudo apt-get update') &&
|
|
107
|
+
run_ok('sudo apt-get install -y docker.io')
|
|
108
|
+
ok = install_compose_package if ok
|
|
109
|
+
run_ok("sudo usermod -aG docker #{@env['USER']}") if ok && @env['USER']
|
|
110
|
+
run_ok('sudo service docker start || sudo systemctl start docker')
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def install_docker_compose_plugin
|
|
114
|
+
@out.puts 'Attempting docker compose install (apt)...'
|
|
115
|
+
@actions << 'install_docker_compose_plugin'
|
|
116
|
+
run_ok('sudo apt-get update')
|
|
117
|
+
install_compose_package
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Package naming differs across Ubuntu/Debian variants.
|
|
121
|
+
# Try known options in order.
|
|
122
|
+
def install_compose_package
|
|
123
|
+
run_ok('sudo apt-get install -y docker-compose-plugin') ||
|
|
124
|
+
run_ok('sudo apt-get install -y docker-compose-v2') ||
|
|
125
|
+
run_ok('sudo apt-get install -y docker-compose')
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def summary(mode)
|
|
129
|
+
failed = @checks.reject { |c| c[:ok] }
|
|
130
|
+
required = required_checks(@selected_runtime_mode)
|
|
131
|
+
required_failed = failed.select { |c| required.include?(c[:name]) }
|
|
132
|
+
ready = required_failed.empty?
|
|
133
|
+
exit_code =
|
|
134
|
+
if ready
|
|
135
|
+
0
|
|
136
|
+
elsif mode == :apply && required_failed.any? { |c| c[:name] == 'docker_daemon' }
|
|
137
|
+
2
|
|
138
|
+
else
|
|
139
|
+
1
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
@out.puts '-' * 60
|
|
143
|
+
@out.puts "Checks: #{@checks.count { |c| c[:ok] }}/#{@checks.size} passed"
|
|
144
|
+
@out.puts "Actions: #{@actions.join(', ')}" unless @actions.empty?
|
|
145
|
+
local_runtime_hint
|
|
146
|
+
print_remediation(required_failed, mode)
|
|
147
|
+
@out.puts "Ready: #{ready ? 'YES' : 'NO'}"
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
mode: mode,
|
|
151
|
+
runtime_mode: @selected_runtime_mode,
|
|
152
|
+
checks: @checks,
|
|
153
|
+
actions: @actions,
|
|
154
|
+
ready: ready,
|
|
155
|
+
exit_code: exit_code
|
|
156
|
+
}
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def print_remediation(failed, mode)
|
|
160
|
+
return if failed.empty?
|
|
161
|
+
|
|
162
|
+
failed_names = failed.map { |f| f[:name] }
|
|
163
|
+
@out.puts 'Remediation:'
|
|
164
|
+
|
|
165
|
+
if failed_names.include?('docker_cli')
|
|
166
|
+
@out.puts '- Docker CLI missing in WSL.'
|
|
167
|
+
@out.puts ' REQUIRED on Windows: install Docker Desktop and enable WSL integration.'
|
|
168
|
+
@out.puts ' Download: https://www.docker.com/products/docker-desktop/'
|
|
169
|
+
@out.puts ' Run: sudo apt-get update && sudo apt-get install -y docker.io docker-compose-v2 || sudo apt-get install -y docker-compose'
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
if failed_names.include?('docker_daemon') && wsl?
|
|
173
|
+
@out.puts '- Docker daemon unreachable from WSL.'
|
|
174
|
+
@out.puts ' Docker Desktop with WSL integration is RECOMMENDED for container/multi-version runtime.'
|
|
175
|
+
@out.puts ' Download: https://www.docker.com/products/docker-desktop/'
|
|
176
|
+
@out.puts ' Then:'
|
|
177
|
+
@out.puts ' 1) Open Docker Desktop > Settings > Resources > WSL Integration'
|
|
178
|
+
@out.puts ' 2) Enable integration for this distro'
|
|
179
|
+
@out.puts ' 3) Apply & Restart Docker Desktop'
|
|
180
|
+
@out.puts ' 4) Re-run: docker info'
|
|
181
|
+
@out.puts ' If local R is available, you can run now with local runtime mode:'
|
|
182
|
+
@out.puts ' ruby bin/galaaz-bootstrap --check --runtime local'
|
|
183
|
+
@out.puts ' (Advanced fallback) If you do NOT use Docker Desktop, run a Linux daemon in WSL manually.'
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
if failed_names.include?('docker_compose')
|
|
187
|
+
@out.puts '- Docker compose unavailable.'
|
|
188
|
+
@out.puts ' Try: sudo apt-get install -y docker-compose-v2 || sudo apt-get install -y docker-compose'
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if failed_names.include?('rcpp')
|
|
192
|
+
@out.puts "- Rcpp missing."
|
|
193
|
+
@out.puts " Run: Rscript -e \"install.packages('Rcpp', repos='https://cloud.r-project.org/')\""
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
@out.puts "After fixes, run: ruby bin/galaaz-bootstrap --check"
|
|
197
|
+
@out.puts "(mode=#{mode})"
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def local_runtime_hint
|
|
201
|
+
return unless command_exists?('R')
|
|
202
|
+
|
|
203
|
+
version = run_capture("R --version | head -n 1")
|
|
204
|
+
@out.puts "Local runtime available: #{version}" unless version.empty?
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def required_checks(runtime_mode)
|
|
208
|
+
case runtime_mode
|
|
209
|
+
when :local
|
|
210
|
+
%w[wsl ruby r rcpp]
|
|
211
|
+
else
|
|
212
|
+
%w[wsl docker_cli docker_daemon docker_compose ruby]
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def resolve_runtime_mode(runtime_mode)
|
|
217
|
+
case runtime_mode
|
|
218
|
+
when :docker, :local
|
|
219
|
+
runtime_mode
|
|
220
|
+
when :auto
|
|
221
|
+
if command_exists?('R') && rcpp_ok?
|
|
222
|
+
@out.puts 'Auto runtime selection: local (R + Rcpp already available).'
|
|
223
|
+
:local
|
|
224
|
+
elsif command_exists?('docker')
|
|
225
|
+
@out.puts 'Auto runtime selection: docker (local R not ready).'
|
|
226
|
+
:docker
|
|
227
|
+
else
|
|
228
|
+
@out.puts 'Auto runtime selection: docker (fallback).'
|
|
229
|
+
:docker
|
|
230
|
+
end
|
|
231
|
+
else
|
|
232
|
+
raise ArgumentError, "invalid runtime_mode=#{runtime_mode} (expected :docker, :local, :auto)"
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
def wsl?
|
|
237
|
+
return @wsl_override unless @wsl_override.nil?
|
|
238
|
+
|
|
239
|
+
release = run_capture('uname -r')
|
|
240
|
+
release.downcase.include?('microsoft') || File.exist?('/proc/sys/fs/binfmt_misc/WSLInterop')
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def command_exists?(cmd)
|
|
244
|
+
run_ok("command -v #{cmd}")
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
def docker_daemon_ok?
|
|
248
|
+
run_ok("docker info --format '{{.ServerVersion}}'")
|
|
249
|
+
end
|
|
250
|
+
|
|
251
|
+
def docker_compose_ok?
|
|
252
|
+
run_ok('docker compose version')
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def rcpp_ok?
|
|
256
|
+
run_ok(%q{Rscript -e "quit(status = ifelse(requireNamespace('Rcpp', quietly=TRUE), 0, 1))"})
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def run_ok(cmd)
|
|
260
|
+
ok, out, err, _status = execute(cmd)
|
|
261
|
+
unless ok
|
|
262
|
+
details = [out, err].compact.map(&:strip).reject(&:empty?).join("\n")
|
|
263
|
+
@out.puts("FAILED: #{cmd}")
|
|
264
|
+
@out.puts(details) unless details.empty?
|
|
265
|
+
end
|
|
266
|
+
ok
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def run_capture(cmd)
|
|
270
|
+
_ok, out, _err, _status = execute(cmd)
|
|
271
|
+
out.to_s.strip
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
def execute(cmd)
|
|
275
|
+
@runner.call(cmd)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
def default_runner(cmd)
|
|
279
|
+
out, err, st = Open3.capture3('bash', '-lc', cmd)
|
|
280
|
+
[st.success?, out, err, st.exitstatus]
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|
|
285
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'msgpack'
|
|
4
|
+
|
|
5
|
+
module NewBridge
|
|
6
|
+
# MsgPack-encoded control-plane envelope (see docs/New_Bridge.md).
|
|
7
|
+
module Envelope
|
|
8
|
+
class Error < StandardError; end
|
|
9
|
+
class InvalidEnvelope < Error; end
|
|
10
|
+
|
|
11
|
+
REQUIRED_KEYS = %w[call_id type].freeze
|
|
12
|
+
OPTIONAL_KEYS = %w[parent_id payload status session_id instance_id].freeze
|
|
13
|
+
|
|
14
|
+
module_function
|
|
15
|
+
|
|
16
|
+
def encode(hash)
|
|
17
|
+
h = stringify_keys(hash)
|
|
18
|
+
missing = REQUIRED_KEYS - h.keys
|
|
19
|
+
raise InvalidEnvelope, "missing keys: #{missing.join(', ')}" unless missing.empty?
|
|
20
|
+
|
|
21
|
+
extra = h.keys - (REQUIRED_KEYS + OPTIONAL_KEYS)
|
|
22
|
+
raise InvalidEnvelope, "unknown keys: #{extra.join(', ')}" unless extra.empty?
|
|
23
|
+
|
|
24
|
+
MessagePack.pack(h)
|
|
25
|
+
rescue MessagePack::MalformedFormatError, MessagePack::UnpackError, EOFError => e
|
|
26
|
+
raise Error, "MsgPack pack failed: #{e.message}"
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def decode(bytes)
|
|
30
|
+
raise InvalidEnvelope, 'empty envelope' if bytes.nil? || bytes.empty?
|
|
31
|
+
|
|
32
|
+
h = MessagePack.unpack(bytes)
|
|
33
|
+
unless h.is_a?(Hash)
|
|
34
|
+
raise Error, 'invalid MsgPack envelope: expected a map (Hash)'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
h = stringify_keys(h)
|
|
38
|
+
missing = REQUIRED_KEYS - h.keys
|
|
39
|
+
raise InvalidEnvelope, "missing keys: #{missing.join(', ')}" unless missing.empty?
|
|
40
|
+
|
|
41
|
+
h
|
|
42
|
+
rescue MessagePack::MalformedFormatError, MessagePack::UnpackError, EOFError => e
|
|
43
|
+
raise Error, "invalid MsgPack envelope: #{e.message}"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def stringify_keys(hash)
|
|
47
|
+
hash.each_with_object({}) { |(k, v), out| out[k.to_s] = v }
|
|
48
|
+
end
|
|
49
|
+
private_class_method :stringify_keys
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NewBridge
|
|
4
|
+
# Success/failure wrapper for asynchronous bridge completions (+eval_r_async+).
|
|
5
|
+
class EvalResult
|
|
6
|
+
attr_reader :value, :error
|
|
7
|
+
|
|
8
|
+
def self.success(value)
|
|
9
|
+
new(:ok, value, nil)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.failure(error)
|
|
13
|
+
new(:fail, nil, error)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize(state, value, error)
|
|
17
|
+
@state = state
|
|
18
|
+
@value = value
|
|
19
|
+
@error = error
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def ok?
|
|
23
|
+
@state == :ok
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NewBridge
|
|
4
|
+
# Length-prefixed frames: 4-byte little-endian uint32 payload length, then payload.
|
|
5
|
+
module Framing
|
|
6
|
+
class Error < StandardError; end
|
|
7
|
+
class TruncatedFrame < Error; end
|
|
8
|
+
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
def write_frame(io, payload)
|
|
12
|
+
raise Error, 'payload must be String' unless payload.is_a?(String)
|
|
13
|
+
|
|
14
|
+
io.write([payload.bytesize].pack('V'))
|
|
15
|
+
io.write(payload)
|
|
16
|
+
io.flush
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def read_frame(io)
|
|
20
|
+
len_bytes = read_exact(io, 4)
|
|
21
|
+
len = len_bytes.unpack1('V')
|
|
22
|
+
raise Error, "invalid frame length #{len}" if len > 256 * 1024 * 1024 # 256 MiB cap for phase 0
|
|
23
|
+
|
|
24
|
+
read_exact(io, len)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def read_exact(io, n)
|
|
28
|
+
buf = +''
|
|
29
|
+
while buf.bytesize < n
|
|
30
|
+
chunk = io.read(n - buf.bytesize)
|
|
31
|
+
raise TruncatedFrame, "expected #{n} bytes, got #{buf.bytesize}" if chunk.nil? || chunk.empty?
|
|
32
|
+
|
|
33
|
+
buf << chunk
|
|
34
|
+
end
|
|
35
|
+
buf
|
|
36
|
+
end
|
|
37
|
+
private_class_method :read_exact
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative 'session_client'
|
|
4
|
+
|
|
5
|
+
module NewBridge
|
|
6
|
+
# Phase 2: manage a small pool of external R gatekeeper processes.
|
|
7
|
+
# Each instance is isolated by having its own TCP socket + R process.
|
|
8
|
+
class InstancePoolClient
|
|
9
|
+
class Error < StandardError; end
|
|
10
|
+
|
|
11
|
+
# @param source_path [String] Path to either .cpp file (uses sourceCpp) or .so file (uses dyn.load)
|
|
12
|
+
def initialize(source_path:, instances:, host: '127.0.0.1', r_cmd: 'R')
|
|
13
|
+
@instances = instances
|
|
14
|
+
@host = host
|
|
15
|
+
@r_cmd = r_cmd
|
|
16
|
+
@clients = {}
|
|
17
|
+
instances.each do |instance_id|
|
|
18
|
+
@clients[instance_id] = SessionClient.new(source_path: source_path, host: @host, r_cmd: @r_cmd)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def start
|
|
23
|
+
@instances.each { |iid| @clients.fetch(iid).start }
|
|
24
|
+
self
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def stop
|
|
28
|
+
@clients.each_value(&:stop)
|
|
29
|
+
self
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def eval_r(code, session_id:, instance_id:, timeout: 60)
|
|
33
|
+
client = @clients.fetch(instance_id)
|
|
34
|
+
client.eval_r(code, session_id: session_id, instance_id: instance_id, timeout: timeout)
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|