text:
[![Codeship Status for justin808/react-webpack-rails-tutorial](https://codeship.com/projects/287b26d0-0c05-0133-7a33-02e67aca5f06/status?branch=master)](https://codeship.com/projects/90975)
[![Build Status](https://travis-ci.org/shakacode/react-webpack-rails-tutorial.svg?branch=code_coverage-linting)](https://travis-ci.org/shakacode/react-webpack-rails-tutorial) [![Dependency Status](https://gemnasium.com/shakacode/react-webpack-rails-tutorial.svg)](https://gemnasium.com/shakacode/react-webpack-rails-tutorial) [![Code Climate](https://codeclimate.com/github/shakacode/react-webpack-rails-tutorial/badges/gpa.svg)](https://codeclimate.com/github/shakacode/react-webpack-rails-tutorial) [![Coverage Status](https://coveralls.io/repos/shakacode/react-webpack-rails-tutorial/badge.svg?branch=master&service=github)](https://coveralls.io/github/shakacode/react-webpack-rails-tutorial?branch=master)

# React, Redux, React-Bootstrap, ES7, Webpack Rails
## Server Rendering via the react_on_rails gem

#### Live at [www.reactrails.com](http://www.reactrails.com/)

By Justin Gordon and the Shaka Code Team, [www.shakacode.com](http://www.shakacode.com)

- If this work interests you and you are looking for full or part-time remote work, please [click here](http://forum.shakacode.com/t/railsonmaui-is-hiring-and-partnering-part-time-remote-is-ok/156).
- [ShakaCode](http://www.shakacode.com) is doing Skype plus Slack/Github based coaching for "React on Rails". [Click here](http://www.shakacode.com/work/index.html) for more information.
- Please email us at [contact@shakacode.com](mailto:contact@shakacode.com) if you have a ReactJs + Rails project and are interested in help from our experienced team.
- Please file issues for problems and feature requests.
- Pull requests are welcome! (and a great way to get on the ShakaCode team)
- Feel free to open discussions at [forum.shakacode.com](http://forum.shakacode.com). We love to help!
- We now have a [gitter chat room for this topic](https://gitter.im/shakacode/react-webpack-rails-tutorial) but we prefer our Slack Channel ([email us](mailto:contact@shakacode.com) for an invite).
- Check out the [react_on_rails gem](https://github.com/shakacode/react_on_rails) for easy webpack integration.
- If you came to here from the blog article, this example project has evolved. See [merged pull requests](https://github.com/shakacode/react-webpack-rails-tutorial/pulls?utf8=%E2%9C%93&q=is%3Apr+is%3Amerged) and the [CHANGELOG.md](./CHANGELOG.md).

An outdated full tutorial article behind of the motivation of this system can be found at: [Fast Rich Client Rails Development With Webpack and the ES6 Transpiler](http://www.railsonmaui.com/blog/2014/10/03/integrating-webpack-and-the-es6-transpiler-into-an-existing-rails-project/). Note, this source code repository is way ahead of the tutorial.

# NEWS
We have not yet updated the `react_on_rails` gem generators for the following tasks. We're looking for help to migrate this, if you're interested in contributing to the project. *The tutorial* refers to this repo. The following changes have resulted in lots of differences for the webpack files and visual assets:

1. NOTE: Any references to localhost:3000 *might* need to use 0.0.0.0:3000 until Puma fixes an issue regarding this.
1. **Handling of Sass and Bootstrap**: The tutorial uses CSS modules via Webpack. This is totally different than the older way of having Rails handle Sass/Bootstrap, and having NPM/Webpack handle the Webpack Dev Server. The tutorial now has NPM handle all visual assets. We are using this technique on a new app, and it's awesome!
2. **Hot Reloading with Rails**: The tutorial has different startup scripts than the generators. The dev mode has the WebapackDev server providing the JS and CSS assets to the tutorial. This means you get **HOT RELOADING** of your JS and CSS within your Rails app.

If you did generate a fresh app from React On Rails and want to move to CSS Modules, then see [PR 175: Babel 6 / CSS Modules / Rails hot reloading](https://github.com/shakacode/react-webpack-rails-tutorial/pull/175). Note, while there are probably fixes after this PR was accepted, this has the majority of the changes.

# Example Application
This is a simple example application that illustrates the use of ReactJs to implement a commenting system. Front-end code leverages both ReactJs and Rails asset pipeline while the backend is 100% Rails. It shows off a little bit of the interactivity of a ReactJs application, allowing the commmenter to choose the form layout. `react-bootstrap` is used for the React components. A pure Rails UI generated from scaffolding is shown for comparison.

You can see this tutorial live here: [http://reactrails.com/](http://reactrails.com/)

# Motivation

In no particular order:

- Example of using the [react_on_rails gem](https://github.com/shakacode/react_on_rails) for easy react/webpack integration with Rails.
- Example of React with [CSS Modules](http://glenmaddern.com/articles/css-modules) inside of Rails using Webpack as described in [Smarter CSS builds with Webpack](http://bensmithett.com/smarter-css-builds-with-webpack/).
- Example of enabling hot reloading of both JS and CSS (modules) from your Rails app in development mode. Change your code. Save. Browser updates without a refresh!
- Example of Rails 5 with ReactJs/Redux/React-Router with Webpack and ES7.
- Enabling development of a JS client independently from Rails using the [Webpack Dev Server](https://webpack.github.io/docs/webpack-dev-server.html). You can see this by starting the app and visiting http://localhost:4000
- Enabling the use of npm modules and [Babel](https://babeljs.io/) with a Rails application using [Webpack](https://webpack.github.io/).
- Easily enable retrofitting such a JS framework into an existing Rails app. You don't need a brand new single page app!
- Example setting up Ruby and JavaScript linting in a real project, with corresponding CI rake tasks.

# Technologies involved

See package.json and Gemfile for versions

1. [react_on_rails gem](https://github.com/shakacode/react_on_rails/)
1. [React](http://facebook.github.io/react/)
1. [react-bootstrap](https://react-bootstrap.github.io/)
1. [bootstrap-loader](https://www.npmjs.com/package/bootstrap-loader/)
1. [Redux](https://github.com/reactjs/redux)
1. [react-router](https://github.com/reactjs/react-router)
1. [react-router-redux](https://github.com/reactjs/react-router-redux)
1. [Webpack with hot-reload](https://github.com/webpack/docs/wiki/hot-module-replacement-with-webpack) (for local dev)
1. [Babel transpiler](https://github.com/babel/babel)
1. [Ruby on Rails 5](http://rubyonrails.org/) for backend app and comparison with plain HTML
1. [Heroku for Rails 5 deployment](https://devcenter.heroku.com/articles/getting-started-with-rails5)
1. [Turbolinks 5](https://github.com/turbolinks/turbolinks)

# Basic Setup
1. Be sure that you have Node installed! We suggest [nvm](https://github.com/creationix/nvm), with node version `v5.0` or above. See this article [Updating and using nvm](http://forum.shakacode.com/t/updating-and-using-nvm/293).
1. `git clone git@github.com:shakacode/react-webpack-rails-tutorial.git`
1. `cd react-webpack-rails-tutorial`
1. Check that you have Ruby 2.3.0 or greater
1. Check that you're using the right version of node. Run `nvm list` to check. Use 5.5 or greater.
1. Check that you have Postgres installed. Run `which postgres` to check. Use 9.4 or greater.
1. Check that you have `qmake` installed. Run `which qmake` to check. If missing, follow these instructions: [Installing Qt and compiling capybara-webkit](https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit)
1. `bundle install`
  1. If you get an error installing libv8 on OSX El Capitan, follow these instructions:  [Install therubyracer gem on OSX 10.11 El Capitan](http://stackoverflow.com/a/36388150/1009332) or [this one](http://stackoverflow.com/questions/33475709/install-therubyracer-gem-on-osx-10-11-el-capitan/33475710#33475710).
1. `npm install`
1. `rake db:setup`
1. `foreman start -f Procfile.hot`
  1. Open a browser tab to http://localhost:3000 for the Rails app example with HOT RELOADING
  2. Try Hot Reloading steps below!
1.  `foreman start -f Procfile.express`
  1. Open a browser tab to http://localhost:4000 for the Hot Module Replacement Example just using an express server (no Rails involved). This is good for fast prototyping of React components. However, this setup is not as useful now that we have hot reloading working for Rails!
  2. Try Hot Reloading steps below!
1. `foreman start -f Procfile.static`
  1. Open a browser tab to http://localhost:3000 for the Rails app example.
  2. When you make changes, you have to refresh the browser page.

## Hot Reloading Example: applies to both `Procfile.hot` and `Procfile.express`
1. With the browser open to any JSX file, such as [client/app/bundles/comments/components/CommentBox/CommentBox.jsx](client/app/bundles/comments/components/CommentBox/CommentBox.jsx) and you can change the JSX code, hit save, and you will see the screen update without refreshing the window. This applies to port 3000 and port 4000.
1. Try changing a `.scss` file, such as a color in [client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss](client/app/bundles/comments/components/CommentBox/CommentList/Comment/Comment.scss). You can see port 3000 or 4000 update automatically.
1. Be sure to take a look at the different Procfiles in this directory, as described below.

# KEY COMMANDS
1. Run all linters and tests: `rake`
1. See all npm commands: `npm run`
1. Start all development processes: `foreman start -f Procfile.dev`
1. Start all Rails only development processes: `foreman start -f Procfile.hot`
1. Start development without Rails, using the Webpack Dev Server only: `npm start` (or `foreman start -f Procfile.express`)

# Javascript development without Rails using the Webpack Dev Server

1. Run the node server with file `server-express.js` with command `npm run` or `cd client && node server-express.js`.
2. Point your browser to [http://localhost:4000](http://localhost:4000)

Save a change to a JSX file and see it update immediately in the browser! Note, any browser state still exists, such as what you've typed in the comments box. That's totally different than [Live Reload](http://livereload.com/) which refreshes the browser. Note, we just got this working with your regular Rails server! See below for **Hot Loading**.

# Rails integration

## JS and CSS assets
We're now using Webpack for all Sass and JavaScript assets so we can do CSS Modules within Rails!

1. **Production Deployment**: See [assets.rake](lib/tasks/assets.rake) for we modify the Rails precompile task to deploy assets for production.
1. **Development Mode**: Two flavors: Hot reloading assets (JavaScript & CSS) and Static loading.
   1. **Hot Loading**: We modify the URL in [application.html.erb](app/views/layouts/application.html.erb) based on whether or not we're in production mode using the helpers `env_stylesheet_link_tag` and `env_javascript_include_tag`. *Development mode* uses the Webpack Dev server running on port 3500. Other modes (production/test) use precompiled files. See `Procfile.hot`. `Procfile.dev` also starts this mode. Note, *you don't have to refresh a Rails web page to view changes to JavaScript or CSS*.
  2. **Static Loading**: This uses webpack to create physical files of the assets, both JavaScript and CSS. This is essentially what we had before we enabled *Hot Loading*. You have to *refresh* the page to see changes to JavaScript or CSS. See `Procfile.static`. It is important to note that tests will use the same statically generated files.
  3. Note, the following view helpers do the magic to make this work:
   ```erb
  <%= env_stylesheet_link_tag(static: 'application_static', hot: 'application_non_webpack', options: { media: 'all', 'data-turbolinks-track' => true })  %>
  <%= env_javascript_include_tag(hot: ['http://localhost:3500/vendor-bundle.js', 'http://localhost:3500/app-bundle.js']) %>
  <%= env_javascript_include_tag(static: 'application_static', hot: 'application_non_webpack', options: { 'data-turbolinks-track' => true }) %>
  ```

1. **Testing Mode**: When running tests, it is useful to run `foreman start -f Procfile.spec` in order to have webpack automatically recompile the static bundles. Rspec is configured to automatically check whether or not this process is running. If it is not, it will automatically rebuild the webpack bundle to ensure you are not running tests on stale client code. This is achieved via the `ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)`
line in the `rails_helper.rb` file. If you are using this project as an example and are not using RSpec, you may want to implement similar logic in your own project.

# Webpack configuration
## Config Files

- `webpack.client.base.config.js`: Common **client** configuration file to minimize code duplication for `webpack.client.rails.build.config`, `webpack.client.rails.hot.config`, `webpack.client.express.config`
- `webpack.client.express.config.js`: Webpack configuration for [client/server-express.js](client/server-express.js)
- `webpack.client.rails.build.config.js`: Client side js bundle for deployment and tests.
- `webpack.client.rails.hot.config.js`: Webpack Dev Server bundler for serving rails assets on port 3500, used by [client/server-rails-hot.js](client/server-rails-hot.js), for hot reloading JS and CSS within Rails.
- `webpack.server.rails.build.config.js`: Server side js bundle, used by server rendering.

## Webpack Resources
- [Webpack Docs](http://webpack.github.io/docs/)
- [Webpack Cookbook](https://christianalfoni.github.io/react-webpack-cookbook/)
- Good overview: [Pete Hunt's Webpack Howto](https://github.com/petehunt/webpack-howto)

# Sass, CSS Modules, and Twitter Bootstrap integration
We're using Webpack to handle Sass assets so that we can use CSS modules. The best way to understand how we're handling assets is to close follow this example. We'll be working on more docs soon. If you'd like to give us a hand, that's a great way to learn about this!

For example in [client/app/bundles/comments/components/CommentBox/CommentBox.jsx](client/app/bundles/comments/components/CommentBox/CommentBox.jsx), see how we use standard JavaScript import syntax to refer to class names that come from CSS modules:

```javascript
import css from './CommentBox.scss';

export default class CommentBox extends React.Component {
  render() {
    const { actions, data } = this.props;
    const cssTransitionGroupClassNames = {
      enter: css.elementEnter,
      enterActive: css.elementEnterActive,
      leave: css.elementLeave,
      leaveActive: css.elementLeaveActive,
    };
  }
}
```

## Sass and fonts
The tutorial makes use of a custom font OpenSans-Light. We're doing this to show how to add assets for the CSS processing. The font files are located under [client/app/assets/fonts](client/app/assets/fonts) and are loaded by both the Rails asset pipeline and the Webpack HMR server.

# Process management during development
```
bundle exec foreman start -f <Procfile>
```

1. [`Procfile.dev`](Procfile.dev): Starts the Webpack Dev Server and Rails with Hot Reloading.
2. [`Procfile.hot`](Procfile.hot): Starts the Rails server and the webpack server to provide hot reloading of assets, JavaScript and CSS.
3. [`Procfile.static`](Procfile.static): Starts the Rails server and generates static assets that are used for tests.
4. [`Procfile.express`](Procfile.express): Starts only the Webpack Dev Server.
5. [`Procfile.spec`](Procfile.spec): Starts webpack to create the static files for tests. **Good to know:** If you want to start `rails s` separately to debug in `pry`, then run `Procfile.spec` to generate the assets and run `rails s` in a separate console.
6. [`Procfile.static.trace`](Procfile.static.trace): Same as `Procfile.static` but prints tracing information useful for debugging server rendering.

In general, you want to avoid running more webpack watch processes than you need. The `Procfile.dev`, for example, runs both the express server (Webpack dev server) and the Rails hot assets reloading server.

## Contributors
[The Shaka Code team!](http://www.shakacode.com/about/), led by [Justin Gordon](https://github.com/justin808/), along with with many others. See [contributors.md](docs/contributors.md)

# Open Code of Conduct
This project adheres to the [Open Code of Conduct](http://todogroup.org/opencodeofconduct/#fetch/opensource@github.com). By participating, you are expected to uphold this code.

# RubyMine and WebStorm
Special thanks to [JetBrains](https://www.jetbrains.com) for their great tools: [RubyMine](https://www.jetbrains.com/ruby/) and [WebStorm](https://www.jetbrains.com/webstorm/). Some developers of this project use RubyMine at the top level, mostly for Ruby work, and we use WebStorm opened up to the `client` directory to focus on JSX and Sass files.

## About [ShakaCode](http://www.shakacode.com/)

We hope you read [Who Is ShakaCode](http://www.shakacode.com/2015/09/17/who-is-shaka-code.html) and [Success the ShakaCode Way!](http://www.shakacode.com/2015/11/26/success-the-shakacode-way.html)

Visit [our forums!](http://forum.shakacode.com). We've got a [category dedicated to react_on_rails](http://forum.shakacode.com/c/rails/reactonrails).

If you're looking for consulting on a project using React and Rails, email us at [contact@shakacode.com](mailto:contact@shakacode.com)! You can also join our slack room for some free advice. Email us for an invite.

We're looking for great developers that want to work with Rails + React with a super-run, remote-first, distributed, worldwide team, for our own products, client work, and open source. [More info here](http://www.shakacode.com/about/index.html#work-with-us).


text:
Instapaper API Library for Ruby

# Usage

    l = LaterPaper.new('username','password')

    l.authenticate? # returns true if the username and password are valid

    l.status_code # returns the http status code from the InstaPaper call

    l.add?(url) # will add the url to the account and return true if successfull.

# ToDo

* Remove URL
* Verify if a URL is already in use

# Contributing to LaterPaper

* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
* Fork the project
* Start a feature/bugfix branch
* Commit and push until you are happy with your contribution
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.

# Copyright

Copyright (c) 2011 Jay Shepherd. See LICENSE.txt for
further details.

redpajama_set_name: RedPajamaGithub


text:
using System.Data;
using System.Data.SQLite;

namespace ZendeskTicketExporter.Core.Tests
{
    public class InMemorySQLiteConnection : IDbConnection
    {
        private static readonly string InMemoryConnectionString = "Data Source=:memory:;Version=3;New=True;";

        private readonly SQLiteConnection _conn;

        public InMemorySQLiteConnection()
        {
            _conn = new SQLiteConnection(InMemoryConnectionString);
        }

        public IDbTransaction BeginTransaction(IsolationLevel il)
        {
            return _conn.BeginTransaction(il);
        }

        public IDbTransaction BeginTransaction()
        {
            return _conn.BeginTransaction();
        }

        public void ChangeDatabase(string databaseName)
        {
            ChangeDatabase(databaseName);
        }

        public void Close()
        {
        }

        public string ConnectionString
        {
            get { return InMemoryConnectionString; }
            set { }
        }

        public int ConnectionTimeout
        {
            get { return 60; }
        }

        public IDbCommand CreateCommand()
        {
            return _conn.CreateCommand();
        }

        public string Database
        {
            get { return ":memory:"; }
        }

        public void Open()
        {
            if (_conn.State != ConnectionState.Open)
                _conn.Open();
        }

        public ConnectionState State
        {
            get { return _conn.State; }
        }

        public void Dispose()
        {
        }
    }
}


text:
<?php

namespace Gitonomy\Bundle\CoreBundle\Debug;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;

use Gitonomy\Bundle\CoreBundle\Mailer\DebugMailer;

class MailerDataCollector extends DataCollector
{
    protected $mailer;

    public function __construct(DebugMailer $mailer)
    {
        $this->mailer = $mailer;
    }

    public function collect(Request $request, Response $response, \Exception $exception = null)
    {
        $this->data = array(
            'count' => $this->mailer->getMessageCount()
        );
    }

    public function getName()
    {
        return 'mailer';
    }

    public function getMessageCount()
    {
        return isset($this->data['count']) ? $this->data['count'] : 0;
    }
}


text:
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { AnyPipe } from './any.pipe';
import { BuildingsRatioPipe } from './buildings-ratio.pipe';
import { CountPipe } from './count.pipe';
import { LegendPipe } from './legend.pipe';
import { MapPipe } from './map.pipe';
import { SortedPipe } from './sorted.pipe';

@NgModule({
    declarations: [CountPipe, LegendPipe, AnyPipe, MapPipe, SortedPipe, BuildingsRatioPipe],
    exports: [CountPipe, LegendPipe, AnyPipe, MapPipe, SortedPipe, BuildingsRatioPipe],
    providers: [CountPipe, LegendPipe, AnyPipe, MapPipe, SortedPipe, BuildingsRatioPipe],
    imports: [CommonModule],
})
export class PipesModule {}


text:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var glob = require("glob");
exports.getModules = function (pattern) {
    return new Promise(function (resolve, reject) {
        glob(pattern, {}, function (er, files) {
            resolve(files);
        });
    });
};


text:
<?php

namespace Drupal\Tests\workspaces\Functional;

use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Tests\BrowserTestBase;
use Drupal\workspaces\Entity\Workspace;

/**
 * Tests path aliases with workspaces.
 *
 * @group path
 * @group workspaces
 */
class PathWorkspacesTest extends BrowserTestBase {

  use WorkspaceTestUtilities;

  /**
   * {@inheritdoc}
   */
  protected static $modules = [
    'block',
    'content_translation',
    'node',
    'path',
    'workspaces',
  ];

  /**
   * {@inheritdoc}
   */
  protected $defaultTheme = 'stark';

  /**
   * {@inheritdoc}
   */
  protected function setUp(): void {
    parent::setUp();

    ConfigurableLanguage::createFromLangcode('ro')->save();
    $this->rebuildContainer();

    // Create a content type.
    $this->drupalCreateContentType([
      'name' => 'article',
      'type' => 'article',
    ]);

    $this->drupalLogin($this->rootUser);

    // Enable URL language detection and selection.
    $edit = ['language_interface[enabled][language-url]' => 1];
    $this->drupalGet('admin/config/regional/language/detection');
    $this->submitForm($edit, 'Save settings');

    // Enable translation for article node.
    $edit = [
      'entity_types[node]' => 1,
      'settings[node][article][translatable]' => 1,
      'settings[node][article][fields][path]' => 1,
      'settings[node][article][fields][body]' => 1,
      'settings[node][article][settings][language][language_alterable]' => 1,
    ];
    $this->drupalGet('admin/config/regional/content-language');
    $this->submitForm($edit, 'Save configuration');
    \Drupal::entityTypeManager()->clearCachedDefinitions();

    $this->setupWorkspaceSwitcherBlock();
  }

  /**
   * Tests path aliases with workspaces.
   */
  public function testPathAliases() {
    // Create a published node in Live, without an alias.
    $node = $this->drupalCreateNode([
      'type' => 'article',
      'status' => TRUE,
    ]);

    // Switch to Stage and create an alias for the node.
    $stage = Workspace::load('stage');
    $this->switchToWorkspace($stage);

    $edit = [
      'path[0][alias]' => '/' . $this->randomMachineName(),
    ];
    $this->drupalGet('node/' . $node->id() . '/edit');
    $this->submitForm($edit, 'Save');

    // Check that the node can be accessed in Stage with the given alias.
    $path = $edit['path[0][alias]'];
    $this->assertAccessiblePaths([$path]);

    // Check that the 'preload-paths' cache includes the active workspace ID in
    // the cache key.
    $this->assertNotEmpty(\Drupal::cache('data')->get('preload-paths:stage:/node/1'));
    $this->assertFalse(\Drupal::cache('data')->get('preload-paths:/node/1'));

    // Check that the alias can not be accessed in Live.
    $this->switchToLive();
    $this->assertNotAccessiblePaths([$path]);
    $this->assertFalse(\Drupal::cache('data')->get('preload-paths:/node/1'));

    // Publish the workspace and check that the alias can be accessed in Live.
    $stage->publish();
    $this->assertAccessiblePaths([$path]);
    $this->assertNotEmpty(\Drupal::cache('data')->get('preload-paths:/node/1'));
  }

  /**
   * Tests path aliases with workspaces and user switching.
   */
  public function testPathAliasesUserSwitch() {
    // Create a published node in Live, without an alias.
    $node = $this->drupalCreateNode([
      'type' => 'article',
      'status' => TRUE,
    ]);

    // Switch to Stage and create an alias for the node.
    $stage = Workspace::load('stage');
    $this->switchToWorkspace($stage);

    $edit = [
      'path[0][alias]' => '/' . $this->randomMachineName(),
    ];
    $this->drupalGet('node/' . $node->id() . '/edit');
    $this->submitForm($edit, 'Save');

    // Check that the node can be accessed in Stage with the given alias.
    $path = $edit['path[0][alias]'];
    $this->assertAccessiblePaths([$path]);

    // Check that the 'preload-paths' cache includes the active workspace ID in
    // the cache key.
    $this->assertNotEmpty(\Drupal::cache('data')->get('preload-paths:stage:/node/1'));
    $this->assertFalse(\Drupal::cache('data')->get('preload-paths:/node/1'));

    // Check that the alias can not be accessed in Live, by logging out without
    // an explicit switch.
    $this->drupalLogout();
    $this->assertNotAccessiblePaths([$path]);
    $this->assertFalse(\Drupal::cache('data')->get('preload-paths:/node/1'));

    // Publish the workspace and check that the alias can be accessed in Live.
    $this->drupalLogin($this->rootUser);
    $stage->publish();
    $this->drupalLogout();
    $this->assertAccessiblePaths([$path]);
    $this->assertNotEmpty(\Drupal::cache('data')->get('preload-paths:/node/1'));
  }

  /**
   * Tests path aliases with workspaces for translatable nodes.
   */
  public function testPathAliasesWithTranslation() {
    $stage = Workspace::load('stage');

    // Create one node with a random alias.
    $default_node = $this->drupalCreateNode([
      'type' => 'article',
      'langcode' => 'en',
      'status' => TRUE,
      'path' => '/' . $this->randomMachineName(),
    ]);

    // Add published translation with another alias.
    $this->drupalGet('node/' . $default_node->id());
    $this->drupalGet('node/' . $default_node->id() . '/translations');
    $this->clickLink('Add');
    $edit_translation = [
      'body[0][value]' => $this->randomMachineName(),
      'status[value]' => TRUE,
      'path[0][alias]' => '/' . $this->randomMachineName(),
    ];
    $this->submitForm($edit_translation, 'Save (this translation)');
    // Confirm that the alias works.
    $this->drupalGet('ro' . $edit_translation['path[0][alias]']);
    $this->assertSession()->pageTextContains($edit_translation['body[0][value]']);

    $default_path = $default_node->path->alias;
    $translation_path = 'ro' . $edit_translation['path[0][alias]'];

    $this->assertAccessiblePaths([$default_path, $translation_path]);

    $this->switchToWorkspace($stage);

    $this->assertAccessiblePaths([$default_path, $translation_path]);

    // Create a workspace-specific revision for the translation with a new path
    // alias.
    $edit_new_translation_draft_with_alias = [
      'path[0][alias]' => '/' . $this->randomMachineName(),
    ];
    $this->drupalGet('ro/node/' . $default_node->id() . '/edit');
    $this->submitForm($edit_new_translation_draft_with_alias, 'Save (this translation)');
    $stage_translation_path = 'ro' . $edit_new_translation_draft_with_alias['path[0][alias]'];

    // The new alias of the translation should be available in Stage, but not
    // available in Live.
    $this->assertAccessiblePaths([$default_path, $stage_translation_path]);

    // Check that the previous (Live) path alias no longer works.
    $this->assertNotAccessiblePaths([$translation_path]);

    // Switch out of Stage and check that the initial path aliases still work.
    $this->switchToLive();
    $this->assertAccessiblePaths([$default_path, $translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);

    // Switch back to Stage.
    $this->switchToWorkspace($stage);

    // Create new workspace-specific revision for translation without changing
    // the path alias.
    $edit_new_translation_draft = [
      'body[0][value]' => $this->randomMachineName(),
    ];
    $this->drupalGet('ro/node/' . $default_node->id() . '/edit');
    $this->submitForm($edit_new_translation_draft, 'Save (this translation)');
    // Confirm that the new draft revision was created.
    $this->assertSession()->pageTextContains($edit_new_translation_draft['body[0][value]']);

    // Switch out of Stage and check that the initial path aliases still work.
    $this->switchToLive();
    $this->assertAccessiblePaths([$default_path, $translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);

    // Switch back to Stage.
    $this->switchToWorkspace($stage);
    $this->assertAccessiblePaths([$default_path, $stage_translation_path]);
    $this->assertNotAccessiblePaths([$translation_path]);

    // Create a new workspace-specific revision for translation with path alias
    // from the original language's default revision.
    $edit_new_translation_draft_with_defaults_alias = [
      'path[0][alias]' => $default_node->path->alias,
    ];
    $this->drupalGet('ro/node/' . $default_node->id() . '/edit');
    $this->submitForm($edit_new_translation_draft_with_defaults_alias, 'Save (this translation)');

    // Switch out of Stage and check that the initial path aliases still work.
    $this->switchToLive();
    $this->assertAccessiblePaths([$default_path, $translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);

    // Check that only one path alias (the original one) is available in Stage.
    $this->switchToWorkspace($stage);
    $this->assertAccessiblePaths([$default_path]);
    $this->assertNotAccessiblePaths([$translation_path, $stage_translation_path]);

    // Create new workspace-specific revision for translation with a deleted
    // (empty) path alias.
    $edit_new_translation_draft_empty_alias = [
      'body[0][value]' => $this->randomMachineName(),
      'path[0][alias]' => '',
    ];
    $this->drupalGet('ro/node/' . $default_node->id() . '/edit');
    $this->submitForm($edit_new_translation_draft_empty_alias, 'Save (this translation)');

    // Check that only one path alias (the original one) is available now.
    $this->switchToLive();
    $this->assertAccessiblePaths([$default_path, $translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);

    $this->switchToWorkspace($stage);
    $this->assertAccessiblePaths([$default_path]);
    $this->assertNotAccessiblePaths([$translation_path, $stage_translation_path]);

    // Create a new workspace-specific revision for the translation with a new
    // path alias.
    $edit_new_translation = [
      'body[0][value]' => $this->randomMachineName(),
      'path[0][alias]' => '/' . $this->randomMachineName(),
    ];
    $this->drupalGet('ro/node/' . $default_node->id() . '/edit');
    $this->submitForm($edit_new_translation, 'Save (this translation)');

    // Confirm that the new revision was created.
    $this->assertSession()->pageTextContains($edit_new_translation['body[0][value]']);
    $this->assertSession()->addressEquals('ro' . $edit_new_translation['path[0][alias]']);

    // Check that only the new path alias of the translation can be accessed.
    $new_stage_translation_path = 'ro' . $edit_new_translation['path[0][alias]'];
    $this->assertAccessiblePaths([$default_path, $new_stage_translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);

    // Switch out of Stage and check that none of the workspace-specific path
    // aliases can be accessed.
    $this->switchToLive();
    $this->assertAccessiblePaths([$default_path, $translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path, $new_stage_translation_path]);

    // Publish Stage and check that its path alias for the translation can be
    // accessed.
    $stage->publish();
    $this->assertAccessiblePaths([$default_path, $new_stage_translation_path]);
    $this->assertNotAccessiblePaths([$stage_translation_path]);
  }

  /**
   * Helper callback to verify paths are responding with status 200.
   *
   * @param string[] $paths
   *   An array of paths to check for.
   *
   * @internal
   */
  protected function assertAccessiblePaths(array $paths): void {
    foreach ($paths as $path) {
      $this->drupalGet($path);
      $this->assertSession()->statusCodeEquals(200);
    }
  }

  /**
   * Helper callback to verify paths are responding with status 404.
   *
   * @param string[] $paths
   *   An array of paths to check for.
   *
   * @internal
   */
  protected function assertNotAccessiblePaths(array $paths): void {
    foreach ($paths as $path) {
      $this->drupalGet($path);
      $this->assertSession()->statusCodeEquals(404);
    }
  }

}


text:
std::unique_ptr<telebotxx::BotApi> bot;

const std::string CONFIG_FILE_NAME = "config.json";

using namespace telebotxx;

std::string token;
std::string chat;
std::string photoFile;
std::string photoUrl;

struct TestConfig
{
	TestConfig()
	{
		std::cout << "Performing tests initialization..." << std::endl;

		using namespace rapidjson;
		FILE *pFile = fopen(CONFIG_FILE_NAME.c_str(), "rb");
		if (pFile == NULL)
			throw std::runtime_error("Can not open config file");

		char buffer[2048];
		FileReadStream is(pFile, buffer, sizeof(buffer));
		rapidjson::Document document;
		document.ParseStream<0, UTF8<>, FileReadStream>(is);

		if (!document.IsObject() && document.HasParseError())
			throw std::invalid_argument("Can not parse config file");

		// Read token
		if (document.HasMember("token"))
			if (document["token"].IsString())
				token = document["token"].GetString();
			else
				throw std::invalid_argument("Config error: 'token' must be unsigned int value.");
		else
			throw std::invalid_argument("Config error: 'token' not set.");

		// Read chat
		if (document.HasMember("chat"))
			if (document["chat"].IsString())
				chat = document["chat"].GetString();
			else
				throw std::invalid_argument("Config error: 'chat' must be unsigned int value.");
		else
			throw std::invalid_argument("Config error: 'chat' not set.");

		// Read photo filename
		if (document.HasMember("photo"))
			if (document["photo"].IsString())
				photoFile = document["photo"].GetString();
			else
				throw std::invalid_argument("Config error: 'photo' must be unsigned int value.");
		else
			throw std::invalid_argument("Config error: 'photo' not set.");

		// Read photo URL
		if (document.HasMember("photoURL"))
			if (document["photoURL"].IsString())
				photoUrl = document["photoURL"].GetString();
			else
				throw std::invalid_argument("Config error: 'photoURL' must be unsigned int value.");
		else
			throw std::invalid_argument("Config error: 'photoURL' not set.");

		telebotxx::setDebugMode(true);
	}

	~TestConfig()
	{
		std::cout << "Performing tests cleanup..." << std::endl;
	}
};

BOOST_GLOBAL_FIXTURE(TestConfig);

BOOST_AUTO_TEST_SUITE(TestBotApi)

	BOOST_AUTO_TEST_CASE(DefaultConstructor)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE_NO_THROW(bot.reset(new BotApi(token)));
	}

	BOOST_AUTO_TEST_CASE(SendMessage)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendMessage(ChatId{chat},
										        Text{"Sample text"}
		));
	}

	BOOST_AUTO_TEST_CASE(SendMessageWithMarkdown)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendMessage(ChatId{chat},
										        Text{"[Sample text in markdown](http://google.com/)"},
										        ParseMode::Markdown
		));
	}

	BOOST_AUTO_TEST_CASE(SendMessageWithHtml)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendMessage(ChatId{chat},
										        Text{"Sample text in HTML"},
										        ParseMode::Html
		));
	}

	BOOST_AUTO_TEST_CASE(SendMessageWithoutPreview)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendMessage(ChatId{chat},
										        Text{"http://google.com/"},
										        DisableWebPagePreview()
		));
	}

	BOOST_AUTO_TEST_CASE(SendMessageWithoutNotification)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendMessage(ChatId{chat},
										        Text{"Message without notification"},
										        DisableNotification()
		));
	}

	BOOST_AUTO_TEST_CASE(SendPhotoFile)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendPhoto(chat,
											  Photo{File{photoFile}}
		));
	}

	BOOST_AUTO_TEST_CASE(SendPhotoFileWithCaption)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendPhoto(chat,
											  Photo{File{photoFile}},
											  Caption{"Photo with caption"}
		));
	}

	BOOST_AUTO_TEST_CASE(SendPhotoInMemory)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		std::ifstream file(photoFile, std::ios::binary | std::ios::ate);
		std::size_t size = static_cast<std::size_t>(file.tellg());
		file.seekg(0, std::ios::beg);
		std::vector<char> buffer(size);
		BOOST_REQUIRE(file.read(buffer.data(), size));
		BOOST_REQUIRE_NO_THROW(bot->sendPhoto(chat,
											  Photo{Buffer{buffer.data(), size, photoFile}},
											  Caption{"Photo sent in-memory"}
		));
	}

	BOOST_AUTO_TEST_CASE(SendPhotoUrl)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendPhoto(chat,
											  Photo{Url{photoUrl}},
											  Caption{"Photo sent by URL"}
		));
	}

	BOOST_AUTO_TEST_CASE(SendPhotoWithoutNotification)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		BOOST_REQUIRE_NO_THROW(bot->sendPhoto(chat,
											  Photo{File{photoFile}},
											  Caption{"Photo without notification"},
											  DisableNotification()
		));
	}

	BOOST_AUTO_TEST_CASE(GetUpdates)
	{
		PRINT_TESTNAME;
		BOOST_REQUIRE(bot);
		Updates updates;
		BOOST_REQUIRE_NO_THROW(updates = bot->getUpdates());
		for (auto update : updates)
		{
			if (update->getType() == Update::Type::Message)
			{
				auto& message = std::dynamic_pointer_cast<MessageUpdate>(update)->getMessage();
				if (message.getFrom())
					std::cout << *message.getFrom() << ": ";
				std::cout << message.getText() << std::endl;
			}
		}
	}

BOOST_AUTO_TEST_SUITE_END()


text:
require_relative 'spec_helper'

describe Shoestring::Cache do

  describe "caches to file" do
    before { FileUtils.rm_rf('tmp') }

    it "works when tmp folder doesn't exist" do
      Shoestring::Cache.check(:test) do |old_version|
        'cached_value'
      end

      File.exists?('tmp/.test').must_equal true
    end

    it "doesn't run when cache is the same" do
      Shoestring::Cache.check(:test) do |old_version|
        @called = 1
        'cached_value'
      end

      Shoestring::Cache.check(:test) do |old_version|
        version = 'cached_value'
        if version != old_version.strip
          @called = 2
        end
        version
      end

      @called.must_equal 1
    end

    it "reruns when version does not match cache" do
      Shoestring::Cache.check(:test) do |old_version|
        @called = 1
        'cached_value'
      end

      Shoestring::Cache.check(:test) do |old_version|
        version = 'changed_value'
        if version != old_version.strip
          @called = 2
        end
        version
      end

      @called.must_equal 2
    end
  end

end


text:
using UnrealBuildTool;

public class KingsguardEditor : ModuleRules
{
    public KingsguardEditor(TargetInfo Target)
	{
        bFasterWithoutUnity = true;
        MinFilesUsingPrecompiledHeaderOverride = 1;

        if (Target.Platform == UnrealTargetPlatform.Linux)
        {
            // Hack for LINUXMessageBoxExt
            PublicDependencyModuleNames.AddRange(new string[] { "SDL2" });
        }

		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "UnrealEd", "Slate", "SlateCore", "SlateRHIRenderer", "Kingsguard", "OnlineSubsystem", "OnlineSubsystemUtils", "UMG" });
	}
}


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// Code generated by Microsoft (R) AutoRest Code Generator.

package com.azure.resourcemanager.kusto.generated;

import com.azure.core.util.Context;

/** Samples for Clusters ListOutboundNetworkDependenciesEndpoints. */
public final class ClustersListOutboundNetworkDependenciesEndpointsSamples {
    /*
     * x-ms-original-file: specification/azure-kusto/resource-manager/Microsoft.Kusto/stable/2022-07-07/examples/KustoOutboundNetworkDependenciesList.json
     */
    /**
     * Sample code: Get Kusto cluster outbound network dependencies.
     *
     * @param manager Entry point to KustoManager.
     */
    public static void getKustoClusterOutboundNetworkDependencies(
        com.azure.resourcemanager.kusto.KustoManager manager) {
        manager.clusters().listOutboundNetworkDependenciesEndpoints("kustorptest", "kustoCluster", Context.NONE);
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/rl_video_surface"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.timeslily.ffmpeg.FFmpegSurfaceView
        android:id="@+id/video_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true" />

    <RelativeLayout
        android:id="@+id/rl_top_bar"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:layout_alignParentTop="true"
        android:layout_gravity="top"
        android:background="@drawable/top_background" >

        <TextView
            android:id="@+id/tv_video_name"
            android:layout_width="200dp"
            android:layout_marginLeft="3dp"
            android:layout_height="match_parent"
            android:ellipsize="marquee"
            android:gravity="center"
            android:marqueeRepeatLimit="marquee_forever"
            android:singleLine="true"
            android:text="11111"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_time"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_alignParentRight="true"
            android:gravity="center"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/tv_battery"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@id/tv_time"
            android:gravity="center"
            android:text="100%"
            android:textSize="18sp" />
    </RelativeLayout>

    <ProgressBar
        android:id="@+id/pb_loading"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true" />

    <LinearLayout
        android:id="@+id/ll_bottom_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom"
        android:background="@drawable/bottom_background"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp" >

            <TextView
                android:id="@+id/tv_current_time"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center_horizontal" />

            <LinearLayout
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="6"
                android:background="@drawable/rouded_shape" >

                <SeekBar
                    android:id="@+id/sb_video_seek"
                    android:layout_width="match_parent"
                    android:layout_height="15dp"
                    android:progressDrawable="@drawable/video_seekbar2"
                    android:thumb="@drawable/point" />
            </LinearLayout>

            <TextView
                android:id="@+id/tv_total_time"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:gravity="center" />
        </LinearLayout>

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content" >

            <ImageView
                android:id="@+id/iv_lock"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_marginLeft="30dp"
                android:clickable="true"
                android:src="@drawable/lock_button_selecter" />

            <ImageView
                android:id="@+id/iv_previous"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toLeftOf="@+id/iv_play_pause"
                android:clickable="true"
                android:src="@drawable/previous_button_selecter" />

            <ImageView
                android:id="@+id/iv_play_pause"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_marginLeft="50dp"
                android:layout_marginRight="50dp"
                android:clickable="true"
                android:src="@drawable/play_button_selecter" />

            <ImageView
                android:id="@+id/iv_next"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerVertical="true"
                android:layout_toRightOf="@+id/iv_play_pause"
                android:clickable="true"
                android:src="@drawable/next_button_selecter" />

            <ImageView
                android:id="@+id/iv_full_screen"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_centerVertical="true"
                android:layout_marginRight="30dp"
                android:clickable="true"
                android:src="@drawable/full_screen_button_selector" />
        </RelativeLayout>
    </LinearLayout>

    <ImageView
        android:id="@+id/iv_pause"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:scaleType="center"
        android:src="@drawable/btn_pause_pressed"
        android:visibility="gone" />

    <LinearLayout
        android:id="@+id/ll_volume_bright"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:background="#80000000"
        android:visibility="invisible" >

        <ProgressBar
            android:id="@+id/pb_bright"
            style="@style/Widget.ProgressBar.Vertical2"
            android:layout_width="14dip"
            android:layout_height="120dip"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:max="100"
            android:progress="50" />

        <ProgressBar
            android:id="@+id/pb_volumn"
            style="@style/Widget.ProgressBar.Vertical"
            android:layout_width="14dip"
            android:layout_height="120dip"
            android:layout_marginBottom="10dp"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="10dp"
            android:layout_marginTop="10dp"
            android:max="100"
            android:progress="50" />
    </LinearLayout>

    <TextView
        android:id="@+id/tv_volume_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:drawableLeft="@drawable/volume"
        android:gravity="center_vertical"
        android:textColor="#ffffff"
        android:textSize="50sp"
        android:textStyle="bold"
        android:visibility="invisible" />

    <TextView
        android:id="@+id/tv_brightness_number"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:drawableLeft="@drawable/brightness"
        android:gravity="center_vertical"
        android:textColor="#ffffff"
        android:textSize="50sp"
        android:textStyle="bold"
        android:visibility="invisible" />

    <ImageView
        android:id="@+id/iv_unlock"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:src="@drawable/lock"
        android:visibility="gone" />

</RelativeLayout>


text:
class Ghee

  # ResourceProxy lets us create a virtual
  # proxy for any API resource, utilizing
  # method_missing to handle passing
  # messages to the real object
  #
  class ResourceProxy

    # Undefine methods that might get in the way
    instance_methods.each { |m| undef_method m unless m =~ /^__|instance_eval|instance_variable_get|object_id|respond_to/ }

    include Ghee::CUD

    # Make connection and path_prefix readable
    attr_reader :connection, :path_prefix, :params

    # Expose pagination data
    attr_reader :current_page, :total, :pagination

    # Instantiates proxy with the connection
    # and path_prefix
    #
    # connection - Ghee::Connection object
    # path_prefix - String
    #
    def initialize(connection, path_prefix, params = {})
      params = {} if !params.is_a?Hash
      @connection, @path_prefix, @params = connection, URI.escape(path_prefix), params
    end

    # Method_missing takes any message passed
    # to the ResourceProxy and sends it to the
    # real object
    #
    # message - Message object
    # args* - Arguements passed
    #
    def method_missing(message, *args, &block)
      subject.send(message, *args, &block)
    end

    # Raw is the raw response from the faraday
    # Use this if you need access to status codes
    # or header values
    #
    def raw
      connection.get(path_prefix){|req| req.params.merge!params }
    end

    # Subject is the response body parsed
    # as json
    #
    # Returns json
    #
    def subject
      @subject ||= connection.get(path_prefix){|req| req.params.merge!params }.body
    end

    # Paginate is a helper method to handle
    # request pagination to the github api
    #
    # options - Hash containing pagination params
    # eg;
    #     :per_page => 100, :page => 1
    #
    # Returns self
    #
    def paginate(options)
      @current_page = options.fetch(:page) {raise ArgumentError, ":page parameter required"}
      per_page = options.delete(:per_page) || 30
      response = connection.get do |req|
        req.url path_prefix, :per_page => per_page, :page => current_page
        req.params.merge! params
      end

      if @subject.nil?
        @subject = response.body
      else
        @subject = @subject.concat response.body
      end

      parse_link_header response.headers.delete("link")

      return self
    end

    def all
      return self if pagination && next_page.nil?

      self.paginate :per_page => 100, :page => next_page || 1

      self.all
    end

    # Generate first_page, last_page, next_page, prev_page convienence methods
    %w{ next prev first last }.each do |term|
      define_method "#{term}_page" do
        pagination ? pagination[term.to_sym] ? pagination[term.to_sym][:page] : nil : nil
      end
    end

    private

    def parse_link_header(header)
      return @total = subject.size, @pagination = {} if header.nil?
      require 'cgi'
      pattern = /<(.*)>;\s+rel="(.*)"/
        matches = {}
      header.split(',').each do |m|
        match = pattern.match m
        uri = URI.parse(match[1])
        uri_params = CGI.parse(uri.query)
        page = uri_params["page"].first.to_i
        per_page = uri_params["per_page"] ? uri_params["per_page"].first.to_i : 30
        matches[match[2].to_sym] = {:link => match[1], :page => page, :per_page => per_page}
      end
      @pagination = matches
    end

  end
end


text:
---
layout: post
title:  Task Execution
categories: XAP97
parent: programmers-guide.html
weight: 1100
---

{% summary page %}Task executors allow you to easily execute grid-wide tasks on the space using the GigaSpace API.{% endsummary %}

# Overview

{%section%}
{%column width=50% %}
OpenSpaces comes with support for executing tasks in a collocated asynchronous manner with the Space (processing unit that started an embedded Space). Tasks can be executed directly on a specific cluster member using typical routing declarations. Tasks can also be executed in a "broadcast" mode on all the primary cluster members concurrently and reduced to a single result on the client side. Tasks are completely dynamic both in terms of content and class definitions (the task class definition does not have to be defined within the space classpath).
{%endcolumn%}

{%column width=45% %}
![Executors_task_flow_basic.jpg](/attachment_files/Executors_task_flow_basic.jpg)
{%endcolumn%}
{%endsection%}

{% tip %}
The following [example](/sbp/map-reduce-pattern---executors-example.html) demonstrates how to use the task execution API
{% endtip %}

# Task API

The `Task` interface is defined as follows:

{% highlight java %}
public interface Task<T extends Serializable> extends Serializable {

  /**
   * Computes a result, or throws an exception if unable to do so.
   *
   * @return computed result
   * @throws Exception if unable to compute a result
   */
  T execute() throws Exception;
}
{% endhighlight %}

Here is a simple implementation of a task that accepts a value that will be returned in the execute phase.

{% highlight java %}
public class MyTask implements Task<Integer> {

  private int value;

  public MyTask(int value) {
    this.value = value;
  }

  public Integer execute() throws Exception {
    return value;
  }
}
{% endhighlight %}

Executing the task itself uses the GigaSpace API with a routing value of 2 (the second parameter):

{% highlight java %}
AsyncFuture<Integer> future = gigaSpace.execute(new MyTask(2), 2);
int result = future.get();
{% endhighlight %}

# Async API

`Task` execution is asynchronous in nature, returning an `AyncFuture` as the result of the execution allowing to get the result at a later stage in the code. `AsyncFuture` itself extends `java.util.concurrent.Future`.

The main deficiency of `java.util.concurrent.Future` is the fact that a call to `get` results in a blocking call (either indefinitely or for a specific timeout) causing the execution of a `Task` to not be completely asynchronous in terms of user API flow. `AsyncFuture` adds the ability to register an `AsyncFutureListener` which will be executed once a result arrives. Here are the interfaces for both `AsyncFuture` and `AsyncFutureListener`:

{% highlight java %}
public interface AsyncFuture<V> extends Future<V> {

    void setListener(AsyncFutureListener<V> listener);
}

public interface AsyncFutureListener<T> {

    /**
     * A callback when a result of an async invocation arrives.
     */
    void onResult(AsyncResult<T> result);
}
{% endhighlight %}

Passing the listener can be done by setting it on the `AsyncFuture` or when executing a task using the `GigaSpace` API as an additional parameter.

`AsyncResult` can be used to extract the result or the exception of the execution. Here it is:

{% highlight java %}
public interface AsyncResult<T> {

    /**
     * Returns the result of the async invocation. Returns null
     * in case of an exception. {@link #getException()} should be checked for
     * successful execution.
     */
    T getResult();

    /**
     * In case of an async invocation failure, returns the exception causing it.
     * If the invocation is successful, this method returns null.
     */
    Exception getException();
}
{% endhighlight %}

# Task Routing

When executing a single `Task` there are several ways its routing can be controlled. The simplest form is by passing the routing information as a parameter to the execute command, for example:

{% highlight java %}
AsyncFuture<Integer> future = gigaSpace.execute(new MyTask(2), 2);
int result = future.get();
{% endhighlight %}

The routing parameter value will be used as the routing value. In case it is a POJO defined with a @SpaceRouting on one of its properties, the value of that property will be used as the routing information when passed as a parameter. For example:

{% highlight java %}
public void Order {

  // ...

  @SpaceRouting
  public Integer getOrderRouting() {
    // ...
  }
}

Order order = new Order();
AsyncFuture<Integer> future = gigaSpace.execute(new MyTask(2), order);
int result = future.get();
{% endhighlight %}

Routing information can also be defined on the `Task` itself either using `@SpaceRouting` annotation or using the optional `TaskRoutingProvider` interface (for non annotations based configuration). Here are how they can be used:

{% inittab os_simple_space|top %}
{% tabcontent Annotation %}

{% highlight java %}

public class MyTask implements Task<Integer> {

  private int value;

  public MyTask(int value) {
    this.value = value;
  }

  public Integer execute() throws Exception {
    return value;
  }

  @SpaceRouting
  public Integer routing() {
    return this.value;
  }
}
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Interface %}

{% highlight java %}

public class MyTask implements Task<Integer> implements TaskRoutingProvider {

  private int value;

  public MyTask(int value) {
    this.value = value;
  }

  public Integer execute() throws Exception {
    return value;
  }

  public Integer getRouting() {
    return this.value;
  }
}
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

Once the routing information is defined on the `Task`, it can be executed (without the need for additional parameters):

{% highlight java %}
AsyncFuture<Integer> future = gigaSpace.execute(new MyTask(2));
int result = future.get();
{% endhighlight %}

# DistributedTask API

A `DistributedTask` is a task that ends up executing more than once (concurrently) and returns a result that is a reduced operation of all the different executions.

{% section %}
{% column %}
Phase 1 - Sending the Tasks to be executed:
![DistributedTaskExecution_phase1.jpg](/attachment_files/DistributedTaskExecution_phase1.jpg)
{% endcolumn %}
{% column %}
Phase 2 - Getting the results back to be reduced:
![DistributedTaskExecution_phase2.jpg](/attachment_files/DistributedTaskExecution_phase2.jpg)
{% endcolumn %}
{% endsection %}

Here is the `DistributedTask` API:

{% highlight java %}
public interface AsyncResultsReducer<T, R> {

  R reduce(List<AsyncResult<T>> results) throws Exception;
}

public interface DistributedTask<T extends Serializable, R> extends Task<T>, AsyncResultsReducer<T, R> {
}
{% endhighlight %}

The distributed task interface extends both `Task` and `AsyncResultsReducer`. The `Task` interface is used to execute a specific execution of the distributed task (there will be several executions of it), and the `AsyncResultsReducer` is used to reduce the results of all the executions.

Lets write a (very) simple example of a `DistributedTask`:

{% highlight java %}
public class MyDistTask implements DistributedTask<Integer, Long> {

  public Integer execute() throws Exception {
    return 1;
  }

  public Long reduce(List<AsyncResult<Integer>> results) throws Exception {
    long sum = 0;
    for (AsyncResult<Integer> result : results) {
      if (result.getException() != null) {
        throw result.getException();
      }
      sum += result.getResult();
    }
    return sum;
  }
}
{% endhighlight %}

The above task simply returns `1` for its `execute` operation, and the reducer simply sums all the executions. If there was an exception thrown during the `execute` operation (in our case, it will never happen), the exception will be throws back to the user during the `reduce` operation.

A distributed task is used when either executing a task the is directed to several nodes based on different routing values, or one that is broadcast to all the primary nodes of the cluster. Executing a distributed task on several nodes based on different routing values can be done as follows:

{% highlight java %}
AsyncFuture<Long> future = gigaSpace.execute(new MyDistTask(), 1, 4, 6, 7);
long result = future.get(); // result will be 4
{% endhighlight %}

In the above case, the distributed task is executed (concurrently and asynchronously) on 4 nodes that correspond to routing values of `1`, `4`, `6`, and `7`.

Broadcasting the execution to all current primary nodes can be done by simply executing **just** the distributed task. Here is an example:

{% highlight java %}
AsyncFuture<Long> future = gigaSpace.execute(new MyDistTask());
long result = future.get(); // result will be the number of primary spaces
{% endhighlight %}

In this case, the distributed task will be executed on all the primary spaces of the cluster.

## AsyncResultFilter

When executing a distributed task, results arrive in an asynchronous manner and once all the results have arrived, the `AsyncResultsReducer` is used to reduce them. The `AsyncResultFitler` can be used to as a callback and filter mechanism to be invoked for each result that arrives.

{% highlight java %}
public interface AsyncResultFilter<T> {

    /**
     * Controls what should be done with the results.
     */
    enum Decision {

        /**
         * Continue processing the distributed task.
         */
        CONTINUE,

        /**
         * Break out of the processing of the distributed task and move
         * to the reduce phase.
         */
        BREAK,

        /**
         * Skip this result and continue processing the rest of the results.
         */
        SKIP
    }

    /**
     * A callback invoked for each result that arrives as a result of a distributed task execution allowing
     * to access the result that caused this event, the events received so far, and the total expected results.
     */
    Decision onResult(AsyncResultFilterEvent<T> event);
}
{% endhighlight %}

The filter can be used to control if a result should be used or not (the `SKIP` decision). If a we have enough results and we can move to the reduce phase (the `BREAK` decision). Or, if we should continue accumulating results (the `CONTINUE` decision).

The filter can also be used as a way to be identify that results have arrived and we can do something within our application as a result of that. Note, in this case, make sure that heavy processing should be performed on a separate (probably pooled) thread.

# ExecutorBuilder API

The executor builder API allows to combine several task executions (both distributed ones and non distributed ones) into a seemingly single execution (with a reduce phase). Think of the `ExecutorBuilder` as a cartridge that accumulates all the tasks to be executed, and then executes all of them at once giving back a reduced result (in a concurrent and asynchronous manner). Here is an example of the API:

![executorBuilder.jpg](/attachment_files/executorBuilder.jpg)

{% highlight java %}
AsyncFuture<Integer> future = gigaSpace.executorBuilder(new SumReducer<Integer, Integer>(Integer.class))
                                .add(new MyTask(2))
                                .add(new MyOtherTask(), 3)
                                .add(new MyDistTask())
                                .execute();
Integer result = future.get();
{% endhighlight %}

In the above case, there are several tasks that are "added" to the `ExecutorBuilder`, executed (in a similar manner to a single distributed task) and then reduced using a sum reducer that is provided when building the `ExecutorBuilder`.

The `ExecutorBuilder` can also be passed an optional `AsyncResultFilter` if the reducer also implements it.

{% tip %}
See the [Elastic Distributed Risk Analysis Engine](/sbp/elastic-distributed-calculation-engine.html) for a full `ExecutorBuilder` API example.
{% endtip %}

# Space Injection

The most common scenario for using executors is by interacting with the collocated Space on which the task is executed. A `GigaSpace` instance, which works against a collocated Space can be easily injected either using annotations or using an interface. Here is an example:

{% inittab os_simple_space|top %}
{% tabcontent Annotation %}

{% highlight java %}

public class TemplateCountTask implements DistributedTask<Integer, Long> {

  private Object template;

  @TaskGigaSpace
  private transient GigaSpace gigaSpace;

  public TemplateCountTask(Object template) {
    this.template = template;
  }

  public Integer execute() throws Exception {
    return gigaSpace.count(template);
  }

  public Long reduce(List<AsyncResult<Integer>> results) throws Exception {
    long sum = 0;
    for (AsyncResult<Integer> result : results) {
      if (result.getException() != null) {
        throw result.getException();
      }
      sum += result.getResult();
    }
    return sum;
  }
}
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Interface %}

{% highlight java %}

public class TemplateCountTask implements DistributedTask<Integer, Long>, TaskGigaSpaceAware {

  private Object template;

  private transient GigaSpace gigaSpace;

  public TemplateCountTask(Object template) {
    this.template = template;
  }

  public void setGigaSpace(GigaSpace gigaSpace) {
    this.gigaSpace = gigaSpace;
  }

  public Integer execute() throws Exception {
    return gigaSpace.count(template);
  }

  public Long reduce(List<AsyncResult<Integer>> results) throws Exception {
    long sum = 0;
    for (AsyncResult<Integer> result : results) {
      if (result.getException() != null) {
        throw result.getException();
      }
      sum += result.getResult();
    }
    return sum;
  }
}
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

## Injecting a Clustered Space Proxy

You may use the `ApplicationContextAware` interface to inject a clustered proxy into the Task implementation. This is useful when the Task should access other partitions. See below example:

{% highlight java %}
public class MyTask implements Task<Integer>, ApplicationContextAware {

    @TaskGigaSpace
    private transient GigaSpace colocatedSpace;
    private transient GigaSpace clusteredSpace;

    public MyTask() {
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        clusteredSpace= (GigaSpace) applicationContext.getBean("clusteredGigaSpace");
    }
....
}
{% endhighlight %}

where the pu.xml should have:

{% highlight java %}
<os-core:space id="space" url="/./space" />
<os-core:giga-space id="clusteredGigaSpace" space="space" clustered="true"/>
{% endhighlight %}

# Task Resource Injection

A task might need to make use of resources defined within the processing unit it is executed at (which are not the collocated Space). For example, have access to a bean defined within the collocated processing unit. A `Task` executed goes through the same lifecycle of a bean defined within a processing unit (except for the fact that it is not registered with a processing unit). Thanks to this fact, injecting resources can be done using annotations (`@Autowired` and `@Resource`) or lifecycle interfaces (such as `ApplicationContextAware`).

In order to enable resource injection, the Task must either be annotated with `AutowireTask` or implement the marker interface `AutowireTaskMarker`. Here is an example of injecting a resource of type `OrderDao` registered under the bean name `orderDao`. The `OrderDao` is then used to count the number of orders for each node.

{% highlight java %}
@AutowireTask
public class OrderCountTask implements DistributedTask<Integer, Long> {

  private Object template;

  @Resource(name = "orderDao")
  private transient OrderDao orderDao;

  public Integer execute() throws Exception {
    return orderDao.countOrders();
  }

  public Long reduce(List<AsyncResult<Integer>> results) throws Exception {
    long sum = 0;
    for (AsyncResult<Integer> result : results) {
      if (result.getException() != null) {
        throw result.getException();
      }
      sum += result.getResult();
    }
    return sum;
  }
}
{% endhighlight %}

(remember to add context:annotation-config to the pu)

When enabling autowiring of tasks, OpenSpaces annotations/interface injection can also be used such as `ClusterInfo` injection.

{% info title=Why use @TaskGigaSpace/TaskGigaSpaceAware when you can autowire using standard Spring? %}
You can inject a collocated `GigaSpace` instance to the task using the `@TaskGigaSpace` annotation  implementing the `TaskGigaSpaceAware` interface. However, you can also wire the task through standard Spring dependency injection using the `@AutowireTask` and `@Resource` annotations. However, there's a big difference between the two: the `@TaskGigaSpace` annotation and the `TaskGigaSpaceAware` interface are intentionally designed not to trigger the spring dependency resolution and injection process, since it can be quite costly in terms of performance if executed every time a task is submitted. Therefore, for the common case where you only need to inject the collocated `GigaSpace` instance to the task, it is recommended to use `@TaskGigaSpace` or `TaskGigaSpaceAware`.
{% endinfo %}

# Built in Reducers

OpenSpaces comes with several built in reducers and distributed tasks that can be used to perform common reduce operations (such as Min, Max, Avg and Sum). For example, if you use a simple `Task`:

{% highlight java %}
public class MyTask implements Task<Integer> {

  public Integer execute() throws Exception {
    return 1;
  }
}
{% endhighlight %}

We can easily make a distributed task out of it that sums all the results using the `SumTask`:

{% highlight java %}
AsyncFuture<Integer> future = gigaSpace.execute(new SumTask<Integer, Integer>(Integer.class, new MyTask()));
int result = future.get(); // returns the number of active cluster members
{% endhighlight %}

In the above case, `SumTask` is a distributed task that wraps a simple `Task`. It automatically implements the `reduce` operation by summing all the results. This execution will result in executing a distributed task against all the primaries.

`SumTask` uses internally the `SumReducer` which is just implements `AsyncResultsReducer`. The reducer, by itself, can be used with APIs that just use a reducer, for example, the `ExecutorBuilder` construction.

See the [Aggregators](./aggregators.html) section for more details.

# Transactions

Executors fully support transactions similar to other `GigaSpace` API. Once an `execute` operation is executed within a declarative transaction, it will automatically join it. The transaction itself is then passed to the node the task executed on and added declaratively to it. This means that **any** `GigaSpace` operation performed within the task `execute` operation will automatically join the transaction started on the **client** side.

An exception thrown within the `execute` operation will not cause the transaction to rollback (since it might be a valid exception). Transaction commit/rollback is controlled just by the client the executed the task.

{% tip %}
When executing distributed tasks or tasks that executed on more than one node within the same execution should use the distributed transaction manager. Tasks that execute just on a single node can use the distributed transaction manager, but should use the local transaction manager.
{%endtip%}

{% anchor j.u.c. ExecutorService %}

# j.u.c ExecutorService

OpenSpaces executors support allows to easily implement java.util.concurrent.ExecutorService which allows to support the `ExecutorService` API and executed `Callable` and `Runnable` as tasks within the Space. Here is an example of how to get an `ExecutorService` implementation based on OpenSpaces executors and use it:

{% highlight java %}
ExecutorService executorService = TaskExecutors.newExecutorService(gigaSpace);
Future<Integer> future = executorService.submit(new MyCallable());
int result = future.get();
{% endhighlight %}

The `java.util.concurrent` support also comes with built in adapters from `Callable`/`Runnable` to `Task`/`DistributedTask`. The adapters are used internally to implement the `ExecutorService`, but can be used on their own. The adapters can be constructed easily using utility methods found within the `TaskExecutors` factory. Here is an example:

{% highlight java %}
// convert a simple callable to task
Task<Integer> task1 = TaskExecutors.task(new MyCallable());
// convert a simple callable to distributed task
DistributedTask<Integer> task2 = TaskExecutors.task(new MyCallable(),
                                      new SumReducer<Integer, Integer>(Integer.class));
{% endhighlight %}