It should contain at least:
#------------------------------------------------------------
# CBRAIN Work Paths
#------------------------------------------------------------
cb=~/CBRAIN
p=$cb/BrainPortal
pl=$p/lib
ph=$p/app/helpers
pc=$p/app/controllers
pss=$p/public/stylesheets
pjs=$p/public/javascripts
pm=$p/app/models
pv=$p/app/views
pi=$p/config/initializers
Each is a Rails application.
Bourreau/... is mostly symbolic links.
Each can potentially connect to a distinct database.
Recommended for development work:
Rails is a MVC framework, so you'll find
models/, views/ and controllers/.
Some files are provided by Rails, some by CBRAIN.
added_core_extensions/ config_portal.rb.TEMPLATE new_framework_defaults.rb application_controller_renderer.rb cookies_serializer.rb rack_config.rb assets.rb filter_parameter_logging.rb session_store.rb backtrace_silencers.rb inflections.rb validation_portal.rb cbrain.rb initialize_console.rb wrap_parameters.rb cbrain_deprecation_tmp.rb listen_temp_monkeypatch.rb config_portal.rb mime_types.rb
The main difference are:
It searches in many categories: files, tasks, users, groups, tools, etc.
If it finds a single record in a category, it sets a variable with a single letter name (e.g. @f for a file, @u for the user).
If it finds several records, its sets an array of results to a variable with two letters (e.g. @ff for many files, @uu for many user).
pv works with Userfile, CbrainTask, User, Group, DataProvider, RemoteResource, Site and Tool ToolConfig.
tv works with anything that has .attributes or .to_h
C> CBRAIN System Checks starting, 2019-03-29 19:17:24 -0400
C> Ruby 2.4.1 on Rails 5.0.6, environment is set to 'development'
C> CBRAIN instance is named 'PID-51004'
C> Hostname is 'bianca.cbrain.mcgill.ca'
C> CBRAIN identified boot mode: console
(more messages...)
C> CBRAIN BrainPortal validation completed, 2019-03-29 19:17:28 -0400
Loading development environment (Rails 5.0.6)
C> CBRAIN Rails Console Initialization starting
Current user is now: admin
Current project is now: (nil)
Welcome the the CBRAIN Rails Console
To get a summary of the extra CBRAIN features, type 'cbhelp'.
Bianca :001 > █
C> CBRAIN System Checks starting, 2019-03-29 19:28:04 -0400 C> Ruby 2.4.1 on Rails 5.0.6, environment is set to 'development' C> CBRAIN instance is named 'PID-51216' C> Hostname is 'bianca.cbrain.mcgill.ca' C> CBRAIN identified boot mode: console C> - Note: You can skip all CBRAIN validations by temporarily setting the C> environment variable 'CBRAIN_SKIP_VALIDATIONS' to '1'. C> Ensuring that this CBRAIN app is registered in the DB... C> - This CBRAIN app is named 'Bianca' and is registered. C> Ensuring that the Sys::ProcTable gem is operational... C> - All good. Found process name: ruby C> Setting time zone for application... C> - Time zone set to 'Eastern Time (US & Canada)'.
C> Making sure we can track file revision numbers. C> - Revisions are fetched using: git C> Cleaning up old SyncStatus objects... C> - No SyncStatus objects are associated with obsolete resources. C> - No SyncStatus objects are associated with obsolete files. C> Checking to see if Data Provider cache is valid... C> Checking to see if Data Provider cache needs cleaning up... C> - Wiping old files in Data Provider cache (in background). C> Current application tag or revision: 5.1.1-4 C> Current Git branch: master
C> CbrainTask::BidsAppHandler: Integrated CbrainTask::BIDSAppFMRIprep C> CbrainTask::BidsAppHandler: Integrated CbrainTask::BIDSAppFreesurferReconAll C> CbrainTask::BidsAppHandler: Integrated CbrainTask::BIDSExample2 C> CbrainTask::BidsAppHandler: Integrated CbrainTask::ExampleGoodbidsapp ... C> Integrated CbrainTask::BEst from descriptor 'best_toolbox.json' C> Integrated CbrainTask::NiakFmriPreprocess from descriptor 'FmriPreprocess.json' C> Integrated CbrainTask::FslAnat from descriptor 'fsl_anat.json' C> Integrated CbrainTask::FslBet from descriptor 'fsl_bet.json' C> Integrated CbrainTask::FslEddyCudaForHcp from descriptor 'fsl_eddy_hcp_cuda.json' C> Integrated CbrainTask::FslFast from descriptor 'fsl_fast.json' ...
C> Checking for pending migrations... C> Checking if the BrainPortal database needs a sanity check... C> Making sure we have a SSH agent to provide our credentials... C> - Found existing agent: PID=13587 SOCK=/Users/prioux/CBRAIN/BrainPortal/tmp/ sockets/ssh-agent.portal.sock C> Making sure we have a CBRAIN key for the agent... C> - Added identity to agent from file: '/Users/prioux/.ssh/id_cbrain_portal'. C> Starting automatic Agent Locker in background... C> - Locker already being created. (/Users/prioux/CBRAIN/BrainPortal/tmp/AgentLocker.lock) C> CBRAIN BrainPortal validation completed, 2019-03-29 19:28:09 -0400
Both methods support -d to demonize.
Example of ps process names you could see:
# Creates a custom log entry with the revision info about +anobject+,
# which is any object or class, supplied as the first argument. Its
# revision_info will be extracted for the final message.
#
# Using this method on an ActiveRecord +obj+ with the class +Abcd+
# in argument, like this:
#
# obj.addlog_revinfo(Abcd,"hello")
#
# results is a log entry like this one:
#
# "Abcd revision 123 prioux 2009-05-23 hello"
def addlog_revinfo(anobject, message=nil, caller_level=0)
# code not shown here
end
When generating the doc:
All these variables can be used both when
running the server or running the console.
Some validations are critical and cannot be
avoided, but all others will be skipped.
ActiveRecord internal methods are hidden, only code
from the CBRAIN side is shown.
If only a specific Boutiques task is of interest, its name (e.g. "FslBet")
can be specified in CBRAIN_BOUTIQUES_DUMPTASK
and only that task's code will be dumped.
They are mostly useful when running the server;
console statements are not logged there.
In development, the logs contain SQL statements that
are colored by type of action, and also include SQL time information.
Group Load (2.3ms) SELECT `groups`.* FROM `groups` INNER JOIN `groups_users` ON `groups`.`id` = `groups_users`.`group_id` WHERE `groups_users`.`user_id` = 1 ORDER BY `groups`.`name` ASC EveryoneGroup Load (0.4ms) SELECT `groups`.* FROM `groups` WHERE `groups`.`type` IN ('EveryoneGroup') AND `groups`.`name` = 'everyone' LIMIT 1 Tool Load (0.6ms) SELECT `tools`.* FROM `tools` WHERE (category <> 'background') (2.7ms) SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `cbrain_tasks` WHERE (cbrain_tasks.status <> 'Preset' AND cbrain_tasks.status <> 'SitePreset') AND (cbrain_tasks.workdir_archived = 0 OR cbrain_tasks.workdir_archived IS NULL) AND `cbrain_tasks`.`user_id` IN (1, 2, 3, 4, 5, 6, 8, 11, 23, 26, 27, 28, 29, 30, 31, 32, 34, 37, 43, 44, 45, 46, 51, 58, 59, 60, 61, 71) AND `cbrain_tasks`.`bourreau_id` IN (2, 5, 8, 9, 10, 11, 12) LIMIT 10) subquery_for_count CACHE (0.0ms) SELECT `groups`.* FROM `groups` WHERE `groups`.`id` = 2 LIMIT 1 Rendered portal/welcome.html.erb within layouts/application (448.1ms) Rendered layouts/_section_account.html.erb (7.3ms) CACHE (0.1ms) SELECT `remote_resources`.* FROM `remote_resources` WHERE `remote_resources`.`id` = 1 LIMIT 1 Rendered layouts/_section_menu.html.erb (7.7ms) Rendered messages/_message_display.html.erb (0.5ms) Rendered layouts/_section_main.html.erb (3.1ms) Rendered layouts/_section_footer.html.erb (0.4ms) User: admin on instance PID-3162 from localhost (127.0.0.1) using Firefox 66.0
CBRAIN provides variations that colorize the output:
Method | Effect in logs or terminal |
---|---|
puts_red "hello" | hello |
puts_green "goodbye" | goodbye |
puts_blue "why" | why |
puts_yellow "why" | why |
puts_magenta "hello" | hello |
puts_cyan "goodbye" | goodbye |
puts_timer "Checking code"
long_step_one()
puts_timer "Finished step 1", "green"
long_step_two()
puts_timer "Finished step 2", "red"
Checking code Finished step 1: diff= 46.345642s / cumul= 46.345642s Finished step 2: diff= 30.784296s / cumul= 77.129938s
It can return the filename and line number where a
method was defined.
IMPORTANT: because of PTY allocation conflicts, use a shell distinct from the one the bourreau master connection was started from.
IMPORTANT: Hitting CTRL-C exits from the Bourreau's console!
The test framework is all under BrainPortal/spec/.
A requirement: the test database must exist.
The DB will be cleaned and reseeded as needed.
Another day maybe.
Both frameworks use the same set of small test
spec files called reqfiles.
Everything is under BrainPortal/test_api.
Note: verbosity and debug traces can be obtained
with -v 2 to -v 9. Default is -v 1; -v 0 is silent.
Note: verbosity and debug traces can be obtained
with -v 2 to -v 9. Default is -v 1; -v 0 is silent.
Information should propagate between them in that cycle:
From my GIT presentation (PDF)
The code is all templated in BrainPortal/lib/cbrain_task_generators.
The file "schema_task_generator.rb" generates everything using the JSON descriptor, and the content of templates/*.erb
In a production environment, the Rails server does not serve them, but assumes another more efficient server will provide them.
Some assets live in BrainPortal/app/assets and are compiled into .../public/assets/.
class CbrainLog < TextFile
All of this is performed in the console:
All of this is performed in the console:
has_viewer :no_color
<pre>
<% content = @userfile.cache_readhandle { |fh| fh.read } %>
<%= content.gsub(/\e\[[\d\;]*m/,"") %>
</pre>
has_viewer :no_color, :if => Proc.new { checks_here }
https://github.com/aces/cbrain/wiki/CbrainTask-Programmer-Guide
The file is a more or less a DSL with an easy-to-read structure.
The action is a query: how many files does a user have,
and what is the total disk space taken by them?
def filecount
puts_red "MY API STARTING"
myfiles = current_user.userfiles
@numfiles = myfiles.count
@totsize = myfiles.sum(:size)
puts_green "MY API END"
end
resources :users, :except => [ :edit ] do member do get 'change_password' post 'switch' end collection do get 'filecount' get 'request_password' post 'send_password' end end
{ "numfiles": <%= @numfiles %>, "totsize": <%= @totsize %> }
My <i>HTML</i> report: numfile=<%= @numfiles %>, totsize=<%= @totsize %>
Project management:
Marc-Étienne Rousseau
Shawn Brown