text:
module QA
  RSpec.describe 'Create' do
    context 'Wiki' do
      describe 'testing wiki content manipulation inside a project' do
        let(:new_wiki_title) { "just_another_wiki_page" }
        let(:new_wiki_content) { "this content is changed or added" }
        let(:commit_message) { "this is a new addition to the wiki" }

        let(:wiki) { Resource::Wiki::ProjectPage.fabricate_via_api! }

        before do
          Flow::Login.sign_in
        end

        it 'by manipulating content on the page', status_issue: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/857' do
          wiki.visit!

          Page::Project::Wiki::Show.perform(&:click_edit)

          Page::Project::Wiki::Edit.perform do |edit|
            edit.set_title new_wiki_title
            edit.set_content new_wiki_content
            edit.set_message commit_message
          end

          Page::Project::Wiki::Edit.perform(&:click_save_changes)

          Page::Project::Wiki::Show.perform do |wiki|
            expect(wiki).to have_title new_wiki_title
            expect(wiki).to have_content new_wiki_content
          end
        end

        it 'by manipulating content on the page using git push', status_issue: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/858' do
          Resource::Repository::WikiPush.fabricate! do |push|
            push.file_content = new_wiki_content
            push.commit_message = commit_message
            push.wiki = wiki
            push.new_branch = false
          end.visit!

          Page::Project::Wiki::Show.perform do |wiki|
            expect(wiki).to have_content new_wiki_content
          end
        end
      end
    end
  end
end


text:
namespace Editor
{
    public class DecorationAction : EquationAction
    {
        public CharacterDecorationInfo [] CharacterDecorations { get; set; }
        public bool Added { get; set; }

        public DecorationAction(ISupportsUndo executor, CharacterDecorationInfo [] cdi, bool added)
            : base(executor)
        {
            Added = added;
            CharacterDecorations = cdi;
        }

        public DecorationAction(ISupportsUndo executor, CharacterDecorationInfo[] cdi)
            : base(executor)
        {
            CharacterDecorations = cdi;
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
---
layout: post101
title:  Event Driven Remoting
categories: XAP101
parent: space-based-remoting-overview.html
weight: 300
---

{% summary%}{%endsummary%}

{%comment%}
{% summary  %}Event Driven Remoting allows you to use remote invocations of POJO services, with the space as the transport layer using a polling container on the space side to process the invocations{% endsummary %}

# Overview
{%endcomment%}

Event Driven remoting is characterized by the nature of how the client communicates with the server. Under the wires, event driven remoting uses the space write and take capabilities. The client writes an internal invocation Entry, that holds the different invocation information (such as service name, method name, and arguments) and then waits for a response (by using blocking take on an expected response). The server, meanwhile, waits (by using OpenSpaces event containers) for internal invocation entries, and once one arrives, it executes the requested service and writes back a response.

{% refer %}
You may find an Event Driven Remoting example in the [Event Driven Remoting Example best practice](/sbp/event-driven-remoting-example.html) section.
{% endrefer %}

# Defining the Contract

In order to support remoting, the first step is to define the contract between the client and the server. In our case, the contract is a simple Java interface. Here is an example:

{% highlight java %}
public interface IDataProcessor {

    /**
     * Process a given Data object, returning the processed Data object.
     */
    Data processData(Data data);
}
{% endhighlight %}

{% note %}
The `Data` object should be `Serializable`, or better yet, `Externalizable` (for better performance).
{%endnote%}

# Implementing the Contract

Next, an implementation of this contract needs to be provided. This implementation will "live" on the server side. Here is a sample implementation:

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

{% highlight java %}
@RemotingService
public class DataProcessor implements IDataProcessor {

    public Data processData(Data data) {
    	data.setProcessor(true);
    	return data;
    }
}
{% endhighlight %}

{% endtabcontent %}
{% tabcontent XML %}

{% highlight java %}
public class DataProcessor implements IDataProcessor {

    public Data processData(Data data) {
    	data.setProcessor(true);
    	return data;
    }
}
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

The XML tab corresponds to exporting the service using xml configuration. The Annotation tab corresponds to exporting the service using annotations.

# Exporting the Service Over the Space

The next step is exporting the service over the space. Exporting the service is done on the server side. As with other Spring remoting support, exporting the service and the method of exporting the service is a configuration time decision. Here is an example of a Spring XML configuration:

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

{% highlight xml %}

<context:component-scan base-package="com.mycompany"/>

<os-remoting:annotation-support />

<os-core:embedded-space id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<os-remoting:service-exporter id="serviceExporter" />

<os-events:polling-container id="eventContainer" giga-space="gigaSpace">

    <os-events:listener ref="serviceExporter"/>

</os-events:polling-container>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Namespace %}

{% highlight xml %}

<os-core:embedded-space id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<bean id="dataProcessor" class="DataProcessor" />

<os-remoting:service-exporter id="serviceExporter">
     <os-remoting:service ref="dataProcessor"/>
</os-remoting:service-exporter>

<os-events:polling-container id="eventContainer" giga-space="gigaSpace">

    <os-events:listener ref="serviceExporter"/>

</os-events:polling-container>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.EmbeddedSpaceFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="DataProcessor" />

<bean id="serviceExporter" class="org.openspaces.remoting.SpaceRemotingServiceExporter">
    <property name="services">
        <list>
            <ref bean="dataProcessor" />
        </list>
    </property>
</bean>

<bean id="eventContainer" class="org.openspaces.events.polling.SimplePollingEventListenerContainer">
    <property name="eventListener" ref="serviceExporter">
</bean>
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

Exporting the service as a remote space service uses the [event polling container](./polling-container.html). The polling container automatically listens to internal `EventDrivenSpaceRemotingEntry` objects, and writes back an updated `EventDrivenSpaceRemotingEntry` to the space. All polling event container features, such as transactions and different receive handlers can be used with Space remoting.

## Exporting a Service Non-Collocated with the Space

With the above example the Service is collocated with the space. There might be scenarios where the service might be running as part of a separate PU where the space and the service running in different PUs. In this case the Service configuration should use a polling container configured in non-blocking mode:

{% highlight xml %}
   <os-core:space-proxy  id="space" name="mySpace"/>

   <os-core:giga-space id="gigaspace" space="space" tx-manager="transactionManager"/>

   <bean id="SimpleServiceImpl" class="example.eventremoting.service.SimpleServiceImpl"/>

   <os-remoting:service-exporter id="ServiceExporter" >
	<os-remoting:service ref="SimpleServiceImpl"/>
   </os-remoting:service-exporter>

    <os-core:distributed-tx-manager id="transactionManager" />

    <os-events:polling-container id="simpleServiceAsyncContainer" giga-space="gigaspace">
	    <os-events:listener ref="ServiceExporter" />
    	<os-events:tx-support tx-manager="transactionManager" tx-timeout="30000" />

  	<os-events:receive-operation-handler>
        <bean class="org.openspaces.events.polling.receive.SingleTakeReceiveOperationHandler">
            <property name="nonBlocking" value="true" />
            <property name="nonBlockingFactor" value="10" />
        </bean>
    </os-events:receive-operation-handler>

    </os-events:polling-container>
{% endhighlight %}

{% info %}
Usually, exporting services is done on a Processing Unit (or Spring application context) that starts an embedded space.
{%endinfo%}

# Using the Service on the Client-Side

In order to use the exported `IDataProcessor` on the client side, beans should use the `IDataProcessor` interface directly:

{% highlight java %}
public class DataRemoting {

    private IDataProcessor dataProcessor;

    public void setDataProcessor(IDataProcessor dataProcessor) {
        this.dataProcessor = dataProcessor;
    }
}
{% endhighlight %}

Configuring the `IDataProcessor` proxy can be done in the following manner:

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

{% highlight xml %}

<os-core:space-proxy  id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<os-remoting:event-driven-proxy id="dataProcessor" giga-space="gigaSpace"
                   interface="org.openspaces.example.data.common.IDataProcessor" timeout="15000">
</os-remoting:event-driven-proxy>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.SpaceProxyFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="org.openspaces.remoting.EventDrivenSpaceRemotingProxyFactoryBean">
    <property name="gigaSpace" ref="gigaSpace" />
    <property name="serviceInterface" value="org.openspaces.example.data.common.IDataProcessor" />
    <property name="timeout" value="15000" />
</bean>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Code %}

{% highlight java %}
SpaceProxyConfigurer configurer = new SpaceProxyConfigurer("space");

GigaSpace gigaSpace = new GigaSpaceConfigurer(configurer).gigaSpace();

IDataProcessor dataProcessor = new EventDrivenRemotingProxyConfigurer<IDataProcessor>(gigaSpace, IDataProcessor.class)
                               .timeout(15000)
                               .proxy();

DataRemoting dataRemoting = new DataRemoting();

dataRemoting.setDataProcessor(dataProcessor);
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

The above example uses the `event-driven-proxy` bean in order to create the remoting proxy, which can then be injected into the `DataRemoting` object. OpenSpaces remoting also allows you to inject the remoting proxy directly into the remoting service property using annotations. Here is an example using the `DataRemoting` class:

{% highlight java %}
public class DataRemoting {

    @EventDrivenProxy(timeout=15000)
    private IDataProcessor dataProcessor;

    // ...
}
{% endhighlight %}

If there are more than one `GigaSpace` beans defined within the application context, the ID of the `giga-space` bean needs to be defined on the annotations.

In order to enable this feature, the following element needs to be added to the application context XML:

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

{% highlight xml %}

<os-remoting:annotation-support />
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.remoting.RemotingAnnotationBeanPostProcessor" />
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

## Remote Routing Handler

Many times, space remoting is done by exporting services in a space with a partitioned cluster topology. The service is exported when working directly with a cluster member (and not against the whole space cluster). When working with such a topology, the client side remoting automatically generates a random routing index value (using the newly created remote invocation object hashcode). In order to control the routing index, the following interface can be implemented:

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

    /**
     * Returns the routing field value based on the remoting invocation. If null
     * is returned, will use internal calcualtion of the routing index.
     */
    T computeRouting(SpaceRemotingInvocation remotingEntry);
}
{% endhighlight %}

Here is a sample implementation which uses the first parameter `Data` object type as the routing index.

{% highlight java %}
public class DataRemoteRoutingHandler implements RemoteRoutingHandler<Long> {

    public Long computeRouting(SpaceRemotingInvocation remotingEntry) {
        if (remotingEntry.getMethodName().equals("processData")) {
            Data data = (Data) remotingEntry.getArguments()[0];
            return data.getType();
        }
        return null;
    }
}
{% endhighlight %}

Finally, the wiring is done in the following manner:

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

{% highlight xml %}

<os-core:space-proxy id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<os-remoting:event-driven-proxy id="dataProcessor" giga-space="gigaSpace"
                   interface="org.openspaces.example.data.common.IDataProcessor" timeout="15000">
    <os-remoting:routing-handler>
        <bean class="org.openspaces.example.data.feeder.support.DataRemoteRoutingHandler"/>
    </os-remoting:routing-handler>
</os-remoting:event-driven-proxy>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.SpaceProxyFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="org.openspaces.remoting.EventDrivenSpaceRemotingProxyFactoryBean">
    <property name="gigaSpace" ref="gigaSpace" />
    <property name="serviceInterface" value="org.openspaces.example.data.common.IDataProcessor" />
    <property name="timeout" value="15000" />
    <property name="remoteRoutingHandler">
        <bean class="org.openspaces.example.data.feeder.support.DataRemoteRoutingHandler"/>
    </property>
</bean>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Code %}

{% highlight java %}
SpaceProxyConfigurer configurer = new SpaceProxyConfigurer("space");

GigaSpace gigaSpace = new GigaSpaceConfigurer(configurer).gigaSpace();

IDataProcessor dataProcessor = new EventDrivenRemotingProxyConfigurer<IDataProcessor>(gigaSpace, IDataProcessor.class)
                               .timeout(15000)
                               .remoteRoutingHandler(new DataRemoteRoutingHandler())
                               .proxy();

DataRemoting dataRemoting = new DataRemoting();

dataRemoting.setDataProcessor(dataProcessor);
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

## Routing Annotation

The above option of using the remote routing handler is very handy when not using annotations. OpenSpaces remoting supports the `Routing` annotation in order to define which of the parameters controls the routing. Here is an example:

{% highlight java %}
public interface MyService {

    void doSomething(@Routing int param1, int param2);
}
{% endhighlight %}

In the above example, routing is done using the `param1` value. When using complex objects, a method name can be specified, which is invoked on the parameter in order to get the actual routing index. Here is an example:

{% highlight java %}
public interface MyService {

    void doSomething(@Routing("getProperty") Value param1, int param2);
}
{% endhighlight %}

In the above example, the `getProperty` method is called on the `Value` object and its return value is used to extract the routing index.

{% note %}
**Note:** Using a [SpaceDocument](./document-api.html) as the annotated routing argument will cause an exception since the `SpaceDocument` class does not define a getter method for each property, but rather a generic getter method to get a property value by its name. The solution is either to extend the `SpaceDocument` class as described in [Extending Space Documents](./document-extending.html), and define the relevant `getProperty` method in the extension class, or use the `RemoteRoutingHandler` mentioned above.
{%endnote%}

# Server Side Services Injection

Each parameter of a remote service can be dynamically injected as if it were a bean defined within the server side (where the service is actually executed) context. This allows you to utilize server side resources and state, within the actual invocation. In order to enable such injection the service interface should either be annotated with `AutowireArguments` annotation, or implement the marker interface `AutowireArgumentsMarker`. Let's see an example:

{% highlight java %}
@AutowireArguments
public interface MyService {

    void doSomething(Value param1);
}
{% endhighlight %}

The above service exposes a service which accepts a `Value` as a parameter. The `Value` parameter, if needed, can be injected dynamically with server side resources and state. For example, if the server side execution needs to be aware of the `ClusterInfo`, the `Value` parameter can implement the `ClusterInfoAware` interface. Here is what it looks like:

{% highlight java %}
public class Value implements ClusterInfoAware {

    private transient ClusterInfo clusterInfo;

    public void setClusterInfo(ClusterInfo clusterInfo) {
        this.clusterInfo = clusterInfo;
    }
}
{% endhighlight %}

{% info %}
Note the fact that `clusterInfo` is transient, so it won't be marshaled after injection back to the client.
{%endinfo%}

Another example is injecting another service that is defined in the server side directly into the parameter, for example, using Spring `@Autowired` annotation.

{% highlight java %}
public class Value implements ClusterInfoAware {

    @Autowired
    private transient AnotherService anotherService;
}
{% endhighlight %}

# Execution Aspects

Space based remoting allows you to inject "aspects" that can wrap the invocation of a remote method on the client side, as well as wrapping the execution of an invocation on the server side.

## The Client Invocation Aspect

The client invocation aspect interface is shown below. You should implement this interface and wire and instance of the implementing class to the client side remote proxy, as explained below:

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

    /**
     * The aspect is called instead of the actual remote invocation. The methodInvocation can
     * be used to access any method related information. The remoting invoker passed can be used
     * to actually invoke the remote invocaiton.
     */
    T invoke(MethodInvocation methodInvocation, RemotingInvoker remotingInvoker) throws Throwable;
}
{% endhighlight %}

An implementation of such an aspect can be configured as follows:

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

{% highlight xml %}

<os-core:space-proxy  id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<os-remoting:event-driven-proxy id="dataProcessor" giga-space="gigaSpace"
                   interface="org.openspaces.example.data.common.IDataProcessor">
    <os-remoting:aspect>
    	<bean class="eg.MyRemoteInvocationAspect" />
    </os-remoting:aspect>
</os-remoting:event-driven-proxy>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.SpaceProxyFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="org.openspaces.remoting.EventDrivenSpaceRemotingProxyFactoryBean">
    <property name="gigaSpace" ref="gigaSpace" />
    <property name="serviceInterface" value="org.openspaces.example.data.common.IDataProcessor" />
    <property name="remoteInvocationAspect">
    	<bean class="eg.MyRemoteInvocationAspect" />
    </property>
</bean>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Code %}

{% highlight java %}
SpaceProxyConfigurer configurer = new SpaceProxyConfigurer("space");

GigaSpace gigaSpace = new GigaSpaceConfigurer(configurer).gigaSpace();

IDataProcessor dataProcessor = new EventDrivenRemotingProxyConfigurer<IDataProcessor>(gigaSpace, IDataProcessor.class)
                               .timeout(15000)
                               .remoteInvocationAspect(new MyRemoteInvocationAspect())
                               .proxy();

DataRemoting dataRemoting = new DataRemoting();

dataRemoting.setDataProcessor(dataProcessor);
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

The instance of the class that implements the `RemoteInvocationAspect` interface will be called by the framework prior to the invocation on the client side. Note that it is up to the aspect implementation to decide whether or not the call should proceed.
If the aspect implementation decides to proceed with the call it should call `method.invoke()` on the provided `method argument`. Otherwise the call to the server will not be performed.

{% anchor serverExecutionApect %}

## The Server Invocation Aspect

The server side invocation aspect interface is shown below. You should implement this interface and wire and instance of the implementing class to the server side service exporter (this is the component that is responsible for exposing your service bean to remote clients):

{% highlight java %}
public interface ServiceExecutionAspect {

    /**
     * A service execution callback allows you to wrap the execution of "server side" service. If
     * actual execution of the service is needed, the invoke method will need to
     * be called on the passed Method, using the service as the actual service to
     * invoke it on, and {@link SpaceRemotingInvocation#getArguments()} as the method arguments.
     *
     *
As an example: method.invoke(service, invocation.getArguments()).
     */
    Object invoke(SpaceRemotingInvocation invocation, Method method, Object service)
                                  throws InvocationTargetException, IllegalAccessException;
}
{% endhighlight %}

An implementation of such an aspect can be configured as follows:

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

{% highlight xml %}

<os-core:embedded-space id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<bean id="dataProcessor" class="DataProcessor" />

<os-remoting:service-exporter id="serviceExporter">
     <os-remoting:aspect>
         <bean class="eg.MyServiceExecutionAspect" />
     </os-remoting:aspect>
     <os-remoting:service ref="dataProcessor"/>
</os-remoting:service-exporter>

<os-events:polling-container id="eventContainer" giga-space="gigaSpace">

    <os-events:listener ref="serviceExporter"/>

</os-events:polling-container>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.EmbeddedSpaceFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="DataProcessor" />

<bean id="serviceExporter" class="org.openspaces.remoting.SpaceRemotingServiceExporter">
    <property name="serviceExecutionAspect">
         <bean class="eg.MyServiceExecutionAspect" />
    </property>
    <property name="services">
        <list>
            <ref bean="dataProcessor" />
        </list>
    </property>
</bean>

<bean id="eventContainer" class="org.openspaces.events.polling.SimplePollingEventListenerContainer">
    <property name="eventListener" ref="serviceExporter">
</bean>
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

The instance of the class that implements the `ServiceExecutionAspect` interface will be called by the framework prior to the invocation of the service bean on the server side. Note that it is up to the aspect implementation to decide whether or not the call should proceed.
If the aspect implementation decides to proceed with the call it should call `method.invoke()` on the provided `method` argument. Otherwise the call to the service bean will not be performed.

# The Metadata Handler

When executing a service using Space based remoting, a set of one or more metadata arguments (in the form of a `java.lang.Object` array) can be passed to the server with the remote invocation. This feature is very handy when you want to pass certain metadata with every remote call that is not part of the arguments of the method you call. A prime example for using meta arguments is security -- i.e. passing security credentials as meta arguments, and using a server side aspect to authorize the execution or to log who actually called the method.

To create the meta arguments on the client side you should implement the following interface and inject an instance of the implementing class to the client side proxy:

{% highlight java %}
public interface MetaArgumentsHandler {

    /**
     * Meta argument handler can control the meta data objects that will be used
     * for the remote invocation.
     */
    Object[] obtainMetaArguments(SpaceRemotingInvocation remotingEntry);
}
{% endhighlight %}

The following snippets show how to plug a custom meta arguments handler to the client side remote proxy. The `Object` array returned by the implementation of the `MetaArgumentsHandler` interface will be sent along with the invocation to server side.

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

{% highlight xml %}

<os-core:space-proxy  id="space" name="mySpace"/>

<os-core:giga-space id="gigaSpace" space="space"/>

<os-remoting:event-driven-proxy id="dataProcessor" giga-space="gigaSpace"
                   interface="org.openspaces.example.data.common.IDataProcessor">
    <os-remoting:meta-arguments-handler>
    	<bean class="eg.MyMetaArgumentsHandler" />
    </os-remoting:meta-arguments-handler>
</os-remoting:event-driven-proxy>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Plain XML %}

{% highlight xml %}

<bean id="space" class="org.openspaces.core.space.SpaceProxyFactoryBean">
    <property name="name" value="space" />
</bean>

<bean id="gigaSpace" class="org.openspaces.core.GigaSpaceFactoryBean">
	<property name="space" ref="space" />
</bean>

<bean id="dataProcessor" class="org.openspaces.remoting.EventDrivenSpaceRemotingProxyFactoryBean">
    <property name="gigaSpace" ref="gigaSpace" />
    <property name="serviceInterface" value="org.openspaces.example.data.common.IDataProcessor" />
    <property name="metaArgumentsHandler">
    	<bean class="eg.MyMetaArgumentsHandler" />
    </property>
</bean>

<bean id="dataRemoting" class="DataRemoting">
    <property name="dataProcessor" ref="dataProcessor" />
</bean>
{% endhighlight %}

{% endtabcontent %}
{% tabcontent Code %}

{% highlight java %}
SpaceProxyConfigurer configurer = new SpaceProxyConfigurer("space");

GigaSpace gigaSpace = new GigaSpaceConfigurer(configurer).gigaSpace();

IDataProcessor dataProcessor = new EventDrivenRemotingProxyConfigurer<IDataProcessor>(gigaSpace, IDataProcessor.class)
                               .timeout(15000)
                               .metaArgumentsHandler(new MyMetaArgumentsHandler())
                               .proxy();

DataRemoting dataRemoting = new DataRemoting();

dataRemoting.setDataProcessor(dataProcessor);
{% endhighlight %}

{% endtabcontent %}
{% endinittab %}

The way to access the meta arguments on the server side is to configure a [server side execution aspect](#serverExecutionApect) by implementing the `ServiceExecutionAspect` and wiring it on the server side as shown [above](#serverExecutionApect). To access the meta arguments, you should call `SpaceRemotingInvocation.getMetaArguments()` on the `invocation` argument provided to the server side aspect.

# Asynchronous Execution

OpenSpaces event driven remoting supports asynchronous execution of remote services using the `java.util.concurrent` `Future` interface. Since the remoting implementation is asynchronous by nature, a `Future` can be used to execute remote services asynchronously.

Since the definition of the interface acts as the contract between the client and the server, asynchronous invocation requires the interface to also support the same business method, returning a `Future` instead of its actual return value. The asynchronous nature is only relevant on the client side, provided by the asynchronous nature of OpenSpaces remoting. There are two options to implement such behavior:

## Different Service Interfaces

The client and the server can have a different service interface definition under the same package and under the same name. The server includes the actual implementation:

{% highlight java %}
public interface SimpleService {

    String say(String message);

    int calc(int value1, int value2);
}
{% endhighlight %}

The client has the same method except it returns a future:

{% highlight java %}
public interface SimpleService {

    Future<String> say(String message);

    int calc(int value1, int value2);
}
{% endhighlight %}

In the above example, the `say()` method uses a `Future` in order to receive the result, while the `calc` method remains synchronous.

{% info %}
When using different services, it is important to include the interface definition in the processing unit `lib` directory (or the compiled classes root directory), so that both client and server use their own definitions and don't share a single one.
{%endinfo%}

## Single Service Interface

Both the client and server share the same interface, with the interface holding both synchronous and asynchronous services. Here is an example:

{% highlight java %}
public interface SimpleService {

    String say(String message);

    Future<String> asyncSay(String message);
}
{% endhighlight %}

In the above case, the server implementation does not need to implement the `asyncSay` method (simply return `null` for the `asyncSay` method). The client side can choose which service to invoke.
You should note the naming convention and the signature of the asynchronous method in this case.
If the regular method looks as follows:
`T doSomething(String arg)`, T being the return value type, then the asynchronous method should have the following signature:
`Future<T> asyncDoSomething(String arg)`.
In other words, the regular method should be prefixed with `async` and the return value should be a `Future` of the original return value.

# Failover

In case of a Primary Backup clusters and Partitioned Sync2Backup clusters, when there is failure of primary space partition, remoting request is transparently forwarded to the backup.

Event Driven Remoting proxy is aware of each partition in the cluster and connection with the failed primary partition will get interrupted/disconnected in case of a failure. Proxy recognizes failure and redirects the request to the backup partition. When the backup becomes ready (any warmup code that needs to run and is ready to accept operations), it will accept this request and process the request. All of this failover behavior is done within the GigaSpaces proxy code and client does not need any extra logic. For more information refer to [Proxy Connectivity]({%currentadmurl%}/tuning-proxy-connectivity.html).

If the backup space does not become ready to accept requests within the configured number of retries, execute request will fail with an Exception.


text:
package com.simplegame.server.bus.bag.dao.filter;

import com.simplegame.core.data.IEntity;
import com.simplegame.core.data.IQueryFilter;

/**
*
* @Author zeusgooogle@gmail.com
* @sine   2015年8月11日 下午3:08:57
*
*/
public interface IQueryCountFilter<T extends IEntity> extends IQueryFilter<T> {

    /**
     * 满足条件
     *
     * @return
     */
    public boolean isSatisfied();

}


text:
package opts

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/docker/engine-api/types/blkiodev"
	"github.com/docker/go-units"
)

// ValidatorThrottleFctType defines a validator function that returns a validated struct and/or an error.
type ValidatorThrottleFctType func(val string) (*blkiodev.ThrottleDevice, error)

// ValidateThrottleBpsDevice validates that the specified string has a valid device-rate format.
func ValidateThrottleBpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
	split := strings.SplitN(val, ":", 2)
	if len(split) != 2 {
		return nil, fmt.Errorf("bad format: %s", val)
	}
	if !strings.HasPrefix(split[0], "/dev/") {
		return nil, fmt.Errorf("bad format for device path: %s", val)
	}
	rate, err := units.RAMInBytes(split[1])
	if err != nil {
		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
	}
	if rate < 0 {
		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>[<unit>]. Number must be a positive integer. Unit is optional and can be kb, mb, or gb", val)
	}

	return &blkiodev.ThrottleDevice{
		Path: split[0],
		Rate: uint64(rate),
	}, nil
}

// ValidateThrottleIOpsDevice validates that the specified string has a valid device-rate format.
func ValidateThrottleIOpsDevice(val string) (*blkiodev.ThrottleDevice, error) {
	split := strings.SplitN(val, ":", 2)
	if len(split) != 2 {
		return nil, fmt.Errorf("bad format: %s", val)
	}
	if !strings.HasPrefix(split[0], "/dev/") {
		return nil, fmt.Errorf("bad format for device path: %s", val)
	}
	rate, err := strconv.ParseUint(split[1], 10, 64)
	if err != nil {
		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
	}
	if rate < 0 {
		return nil, fmt.Errorf("invalid rate for device: %s. The correct format is <device-path>:<number>. Number must be a positive integer", val)
	}

	return &blkiodev.ThrottleDevice{
		Path: split[0],
		Rate: uint64(rate),
	}, nil
}

// ThrottledeviceOpt defines a map of ThrottleDevices
type ThrottledeviceOpt struct {
	values    []*blkiodev.ThrottleDevice
	validator ValidatorThrottleFctType
}

// NewThrottledeviceOpt creates a new ThrottledeviceOpt
func NewThrottledeviceOpt(validator ValidatorThrottleFctType) ThrottledeviceOpt {
	values := []*blkiodev.ThrottleDevice{}
	return ThrottledeviceOpt{
		values:    values,
		validator: validator,
	}
}

// Set validates a ThrottleDevice and sets its name as a key in ThrottledeviceOpt
func (opt *ThrottledeviceOpt) Set(val string) error {
	var value *blkiodev.ThrottleDevice
	if opt.validator != nil {
		v, err := opt.validator(val)
		if err != nil {
			return err
		}
		value = v
	}
	(opt.values) = append((opt.values), value)
	return nil
}

// String returns ThrottledeviceOpt values as a string.
func (opt *ThrottledeviceOpt) String() string {
	var out []string
	for _, v := range opt.values {
		out = append(out, v.String())
	}

	return fmt.Sprintf("%v", out)
}

// GetList returns a slice of pointers to ThrottleDevices.
func (opt *ThrottledeviceOpt) GetList() []*blkiodev.ThrottleDevice {
	var throttledevice []*blkiodev.ThrottleDevice
	for _, v := range opt.values {
		throttledevice = append(throttledevice, v)
	}

	return throttledevice
}

// Type returns the option type
func (opt *ThrottledeviceOpt) Type() string {
	return "throttled-device"
}


text:
.styleSans83.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 83.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans8.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 8.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans11.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 11.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans10.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 10.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans12.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 12.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans23.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 23.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans9.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 9.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans19.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 19.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans7.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 7.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans6.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 6.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans299.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 299.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans12000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 12pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans186.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 186.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans162.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 162.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans5.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 5.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans490.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 490.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans52.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 52.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans152.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 152.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans102.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 102.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans112.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 112.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans14.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 14.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans4.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 4.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans150.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 150.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans126.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 126.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans115.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 115.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans24.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 24.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans21.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 21.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans741.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 741.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans456.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 456.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans76.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 76.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans51.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 51.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans359.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 359.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans411.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 411.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans224.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 224.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans520.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 520.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans655.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 655.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans692.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 692.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans693.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 693.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans961.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 961.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans732.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 732.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans598.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 598.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans35.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 35.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans22.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 22.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans20.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 20.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans15.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 15.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans905.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 905.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans1.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 1.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans906.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 906.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}

.styleSans246.0000<enum PANGO_WEIGHT_NORMAL of type PangoWeight><enum PANGO_STYLE_NORMAL of type PangoStyle> {
    font-family: Sans;
    font-size: 246.0pt;
    font-weight: normal;
    font-style: normal;
    text-align: 0;
    letter-spacing: 0pt;
    line-height: 0pt;
}


text:
package com.viriumdev.curriculab.api;

import java.io.*;

import java.util.*;

import org.apache.http.*;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.*;
import org.apache.http.impl.client.*;

/**
 * Class for forming a connection to Pearson API's
 *
* @author Garrett T. Smith
 */
public class APIConnection {

    public final static int DICTIONARY = 0;
    public final static int BRILLIANT_SERIES = 1;
    public final static int ARTICLE = 2;

    private String baseUrl = "https://api.pearson.com/";
    private final String apiKey = "&apikey=ew3mi87urBtRq3fgRRwNeT9pddywZkfA";

    public final static String SEARCH = "search=";
    public final static String SYNONYMS = "synonyms=";
    public final static String RELATED = "related_words=";
    public final static String HEADWORD = "headword=";
    public final static String TITLE = "title=";
    public final static String CONTENT = "content=";

    private HttpClient client;
    private int api;

    public APIConnection(int apiType) {
        api = apiType;
        switch (apiType) {

            case DICTIONARY:
                baseUrl = baseUrl.concat("v2/dictionaries/entries?");
                break;

            case BRILLIANT_SERIES:
                baseUrl = baseUrl.concat("pearson-education/brilliant/v1/articles?");
                break;
        }

        client = new DefaultHttpClient();
    }

    public APIResponse executeQuery(String queryType, String... keywords) {
        String query = baseUrl;

        query = query.concat(queryType);
        for (int i = 0; i < keywords.length; i++) {
            if (i != keywords.length - 1) {
                query = query.concat(keywords[i] + ",");
            } else {
                query = query.concat(keywords[i]);
            }

        }
        query = query.concat(apiKey);
        //  String jsonStripped = jsonStr.replaceAll("[^A-Za-z0-9 ]", "");
        return rawQuery(query);
    }

    public APIResponse rawQuery(String query) {
        String jsonStr = "";

        HttpGet getRequest = new HttpGet(query);

        try {
            HttpResponse response = client.execute(getRequest);
            HttpEntity respEntity = response.getEntity();
            BufferedInputStream in = new BufferedInputStream(respEntity.getContent());

            int bytesRead = 0;
            byte[] buffer = new byte[2048];

            while ((bytesRead = in.read(buffer)) != -1) {
                String chunk = new String(buffer, 0, bytesRead);
                jsonStr = jsonStr.concat(chunk);

            }

        } catch (IOException ioe) {
            System.err.println("API Request Failed!");
            ioe.printStackTrace();
        }
        return new APIResponse(api, jsonStr);
    }

}


text:
/**
 *
 * Get the value of an element's attribute.
 *
 * @param {String} ID             ID of a WebElement JSON object to route the command to
 * @param {String} attributeName  attribute name of element you want to receive
 *
 * @returns {String|null} The value of the attribute, or null if it is not set on the element.
 *
 * @see  https://code.google.com/p/selenium/wiki/JsonWireProtocol#/session/:sessionId/element/:id/attribute/:name
 * @type protocol
 *
 */

var ErrorHandler = require('../utils/ErrorHandler.js');

module.exports = function elementIdAttribute (id, attributeName) {

    if((typeof id !== 'string' && typeof id !== 'number') || typeof attributeName !== 'string') {
        throw new ErrorHandler.ProtocolError('number or type of arguments don\'t agree with elementIdAttribute protocol command');
    }

    var requestPath = '/session/:sessionId/element/:id/attribute/:name';

    requestPath = requestPath.replace(/:id/gi, id);
    requestPath = requestPath.replace(/:name/gi, attributeName);

    return this.requestHandler.create(requestPath);

};


text:
package com.adaptris.core.services.jdbc.types;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

import java.io.OutputStream;
import java.io.StringWriter;
import java.sql.Types;

import org.apache.commons.io.output.WriterOutputStream;
import org.junit.Before;
import org.junit.Test;

import com.adaptris.jdbc.JdbcResultRow;

@SuppressWarnings("deprecation")
public class ByteArrayColumnTranslatorTest {

  private ByteArrayColumnTranslator translator;

  @Before
  public void setUp() throws Exception {
    translator = new ByteArrayColumnTranslator();
  }

  @Test
  public void testByteToString() throws Exception {
    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", "SomeData".getBytes(), Types.ARRAY);

    String translated = translator.translate(row, 0);

    assertEquals("SomeData", translated);
  }

  @Test
  public void testByteToStringEncoded() throws Exception {
    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", "SomeData".getBytes("UTF-8"), Types.ARRAY);

    String translated = translator.translate(row, 0);

    assertEquals("SomeData", translated);
  }

  @Test
  public void testByteToStringColName() throws Exception {
    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", "SomeData".getBytes(), Types.ARRAY);

    String translated = translator.translate(row, "testField");

    assertEquals("SomeData", translated);
  }

  @Test
  public void testByteIncorrectObject() throws Exception {
    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", new Integer(10), Types.ARRAY);

    try {
      translator.translate(row, "testField");
      fail();
    } catch(Exception ex) {
      //pass, expected
    }
  }

  @Test
  public void testBytesWrite() throws Exception {

    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", "SomeData".getBytes(), Types.ARRAY);

    StringWriter writer = new StringWriter();
    try (OutputStream out = new WriterOutputStream(writer)) {

      translator.write(row, 0, out);
    }
    String translated = writer.toString();
    assertEquals("SomeData", translated);
  }

  @Test
  public void testBytesWrite_ByName() throws Exception {

    JdbcResultRow row = new JdbcResultRow();
    row.setFieldValue("testField", "SomeData".getBytes(), Types.ARRAY);

    StringWriter writer = new StringWriter();
    try (OutputStream out = new WriterOutputStream(writer)) {
      translator.write(row, "testField", out);
    }
    String translated = writer.toString();
    assertEquals("SomeData", translated);
  }
}


text:
CREATE TABLE [dbo].[StatusLog]
(
	[Id] [uniqueidentifier] NOT NULL,
	[CreatedOn] [datetime] NOT NULL,
	[ClientType] [varchar](100)  NOT NULL,
	[ClientId] [uniqueidentifier]  NOT NULL,
	[FromStatus] [varchar](100) NULL,
	[ToStatus] [varchar](100) NOT NULL,
	[StatusDetails] NVARCHAR(2000) NULL,
	[Description] NVARCHAR(2000) NULL,
	CONSTRAINT [PK_StatusLog] PRIMARY KEY CLUSTERED ([Id])
)


text:
  <link href='https://fonts.googleapis.com/css?family=Oswald' rel='stylesheet' type='text/css'>

  {{ site.name }}

    {% for post in site.posts offset:0 limit:10 %}
      {% if post.title == page.title %}

      {% else %}

        {% if post.image.feature %}

        {% endif %}
        {{ post.title }}

{{ post.date | date_to_string }}

      {% endif %}
    {% endfor %}


text:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.data.cosmos.internal.directconnectivity;

import com.azure.data.cosmos.internal.RxDocumentServiceRequest;
import com.azure.data.cosmos.internal.Utils;
import com.azure.data.cosmos.internal.routing.PartitionKeyRangeIdentity;
import reactor.core.publisher.Mono;

public interface IAddressCache {

    /**
     * Resolves physical addresses by either PartitionKeyRangeIdentity.
     *
     *
     * @param request Request is needed only by GatewayAddressCache in the only case when request is name based and user has name based auth token.
     *                PartitionkeyRangeIdentity can be used to locate auth token in this case.
     * @param partitionKeyRangeIdentity target partition key range Id
     * @param forceRefreshPartitionAddresses Whether addresses need to be refreshed as previously resolved addresses were determined to be outdated.
     * @return Physical addresses.
     */
    Mono<Utils.ValueHolder<AddressInformation[]>> tryGetAddresses(
            RxDocumentServiceRequest request,
            PartitionKeyRangeIdentity partitionKeyRangeIdentity,
            boolean forceRefreshPartitionAddresses);
}


text:
from django import template
try:
    # < Django 1.9
    from django.db.models import get_model
except:
    # Django 1.9
    from django.apps.config import AppConfig

register = template.Library()

def do_latest_content(parser, token):
    """
    Returns a specific number of entries for a particular model.
    (If the model is sorted by date published they will be sorted that way
        hence the name get_latest_content.)

    Example usage:

    {% load fetch_content %}
    {% get_latest_content application_name.model_name 5 as foo %}
    {% for bar in foo %}
        {{ bar.attribute }}
    {% endfor %}
    """
    bits = token.split_contents()
    if len(bits) != 5:
        raise template.TemplateSyntaxError("'get_latest_content' takes "
                                           "exactly four arguments")
    model_args = bits[1].split('.')
    if len(model_args) != 2:
        raise template.TemplateSyntaxError("First argument to "
                                           "'get_latest_content' must be an "
                                           "'application name'.'model name' "
                                           "string")
    try:
        # < Django 1.9
        model = get_model(*model_args)
    except:
        # Django 1.9
        model = AppConfig.get_model(*model_args)
    if model is None:
        raise template.TemplateSyntaxError("'get_latest_content' tag got an "
                                           "invalid model: %s" % bits[1])
    return LatestContentNode(model, bits[2], bits[4])

class LatestContentNode(template.Node):
    def __init__(self, model, num, varname):
        self.model = model
        self.num = int(num)
        self.varname = varname

    def render(self, context):
        context[self.varname] = self.model._default_manager.all()[:self.num]
        return ''

register.tag('get_latest_content', do_latest_content)

def do_all_content(parser, token):
    """
    Returns all entries for a particular model.

    Example usage:

    {% load fetch_content %}
    {% get_all_content application_name.model_name as foo %}
    {% for bar in foo %}
        {{ bar.attribute }}
    {% endfor %}
    """
    bits = token.split_contents()
    if len(bits) != 4:
        raise template.TemplateSyntaxError("'get_all_content' takes exactly "
                                           "three arguments")
    model_args = bits[1].split('.')
    if len(model_args) != 2:
        raise template.TemplateSyntaxError("First argument to "
                                           "'get_all_content' must be an "
                                           "'application name'.'model name' "
                                           "string")
    try:
        # < Django 1.9
        model = get_model(*model_args)
    except:
        # Django 1.9
        model = AppConfig.get_model(*model_args)
    if model is None:
        raise template.TemplateSyntaxError("'get_all_content' tag got an "
                                           "invalid model: %s" % bits[1])
    return AllContentNode(model, bits[3])

class AllContentNode(template.Node):
    def __init__(self, model, varname):
        self.model = model
        self.varname = varname

    def render(self, context):
        context[self.varname] = self.model._default_manager.all()
        return ''

register.tag('get_all_content', do_all_content)


text:
extern void RXDeallocate(RXObjectRef _self);

@implementation RXShadowObject

-(void)dealloc {
	RXDeallocate(self);
	return;
	[super dealloc]; // under no circumstances should this be called!
}

@synthesize type;

-(NSString *)typeName {
	return [NSString stringWithUTF8String: RXObjectTypeGetName(self.type)];
}

-(BOOL)isEqual:(id)other {
	return
		[other isKindOfClass: self.class]
	&&	RXEquals(self, other);
}

-(NSString *)description {
	return [(NSString *)RXCopyDescription(self) autorelease];
}

@end


text:
<!DOCTYPE html>

    <meta http-equiv="refresh" content="0;URL=../../openssl_sys/constant.NID_iso.html">

Redirecting to ../../openssl_sys/constant.NID_iso.html...


text:
class DynamicBinaryInstrumentRouting : public X64InterceptRouting {
public:
  DynamicBinaryInstrumentRouting(HookEntry *entry, void *handler) : X64InterceptRouting(entry) {
    this->handler = handler;
  }

  void DispatchRouting();

public:
  void *handler;

private:
  virtual void BuildDynamicBinaryInstrumentRouting();

private:
  void *prologue_dispatch_bridge;

  ;
};

#endif


text:
package griffon.plugins.domain.methods;

/**
 * @author Andres Almiray
 */
public interface InstanceDynamicMethodInvocation extends InstanceMethodInvocation, DynamicMethodInvocation {
}


text:
title: Kevin Eaton, PhD
description: KevinEaton.Net
images: ["/images/sample.jpg"]
---

Welcome!

My name is Kevin Eaton, and I am a proud geek, father, husband, software engineering leader, and Army Chaplain. I am a Chief Software Architect in my current position with over 20 years of professional experience, specializing in Gp (Golang), NodeJS, Typescript / Javascript, React, Svelte, PHP, Elixir, Python, and mobile development. I have tons of DevOps and architecture experience. I love designing strong, reliable, and high quality software. Software craftsmanship is a passion.

I am also an ordained minister, serving the U.S. Army as a Brigade Chaplain.

My favorite hobbies include [Taekwondo](https://www.kiantkd.com) gaming, programming, and running.


text:
module JournalsHelper
  def render_notes(issue, journal, options={})
    content = ''
    editable = User.current.logged? && (User.current.allowed_to?(:edit_issue_notes, issue.project) || (journal.user == User.current && User.current.allowed_to?(:edit_own_issue_notes, issue.project)))
    links = []
    if !journal.notes.blank?
      links << link_to(image_tag('comment.png'),
                       {:controller => 'journals', :action => 'new', :id => issue, :journal_id => journal},
                       :remote => true,
                       :method => 'post',
                       :title => l(:button_quote)) if options[:reply_links]
      links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
                                             { :controller => 'journals', :action => 'edit', :id => journal, :format => 'js' },
                                                :title => l(:button_edit)) if editable
    end
    content << content_tag('div', links.join(' ').html_safe, :class => 'contextual') unless links.empty?
    content << textilizable(journal, :notes)
    css_classes = "wiki"
    css_classes << " editable" if editable
    content_tag('div', content.html_safe, :id => "journal-#{journal.id}-notes", :class => css_classes)
  end

  def link_to_in_place_notes_editor(text, field_id, url, options={})
    onclick = "$.ajax({url: '#{url_for(url)}', type: 'get'}); return false;"
    link_to text, '#', options.merge(:onclick => onclick)
  end
end


text:
package com.bitdubai.fermat_dap_api.layer.all_definition.enums;

import com.bitdubai.fermat_api.layer.all_definition.exceptions.InvalidParameterException;

/**
 * Created by rodrigo on 9/4/15.
 */
public enum State {
    DRAFT ("DFT"),
    PENDING_FINAL ("PFI"),
    FINAL ("FIN");

    private String code;

    State(String code) {
        this.code = code;
    }

    public String getCode() { return this.code ; }

    public static State getByCode(String code)throws InvalidParameterException {
        switch (code) {
            case "DFT":
                return State.DRAFT;
            case "PFI":
                return State.PENDING_FINAL;
            case "FIN":
                return State.FINAL;
            default:
                throw new InvalidParameterException(InvalidParameterException.DEFAULT_MESSAGE, null, "Code Received: " + code, "This Code Is Not Valid for the State enum.");
        }
    }
}


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vortex.gui;

import sandbox.clustering.BarCode;
import java.util.Arrays;

/**
 *
 * @author Nikolay
 */
public class UnityLenBarCode implements BarCode {

    private static final long serialVersionUID = 1L;
    private double[] profile;
    private String[] paramNames;
    private int sideArrayListBeginIdx;

    @Override
    public double[] getRawValues() {
        return profile;
    }

    @Override
    public int getSideVectorBeginIdx() {
        return sideArrayListBeginIdx;
    }

    public UnityLenBarCode(double[] vec, String[] paramNames, int sideArrayListStartIdx) {
        profile = Arrays.copyOf(vec, vec.length);
        this.paramNames = paramNames;
        if (this.paramNames.length > vec.length) {
            this.paramNames = Arrays.copyOf(paramNames, vec.length);
        }
        this.sideArrayListBeginIdx = sideArrayListStartIdx;
        for (int i = 0; i < profile.length; i++) {
            if (profile[i] < -1.0 || profile[i] > 1.0) {
                profile[i] = Math.signum(profile[i]);
            }
        }
    }

    @Override
    public double[] getProfile() {
        return profile;
    }

    @Override
    public String[] getParameterNames() {
        return paramNames;
    }
}


text:
package org.qi4j.entitystore.hazelcast;

import com.hazelcast.config.ClasspathXmlConfig;
import com.hazelcast.config.Config;
import com.hazelcast.config.UrlXmlConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Map;
import org.qi4j.api.configuration.Configuration;
import org.qi4j.api.entity.EntityDescriptor;
import org.qi4j.api.entity.EntityReference;
import org.qi4j.api.injection.scope.This;
import org.qi4j.api.service.ServiceActivation;
import org.qi4j.io.Input;
import org.qi4j.io.Output;
import org.qi4j.io.Receiver;
import org.qi4j.io.Sender;
import org.qi4j.spi.entitystore.EntityNotFoundException;
import org.qi4j.spi.entitystore.EntityStoreException;
import org.qi4j.spi.entitystore.helpers.MapEntityStore;

/**
 * Hazelcast implementation of MapEntityStore.
 */
public class HazelcastEntityStoreMixin
    implements ServiceActivation, HazelcastAccessors, MapEntityStore
{

    private static final String DEFAULT_MAPNAME = "qi4j:entitystore:data";

    @This
    private Configuration<HazelcastConfiguration> config;

    private IMap<String, String> stringMap;
    private HazelcastInstance hazelcastInstance;

    @Override
    public void activateService()
        throws Exception
    {
        HazelcastConfiguration configuration = config.get();
        Config conf = createConfig( configuration );
        hazelcastInstance = Hazelcast.newHazelcastInstance( conf );
        String mapName = DEFAULT_MAPNAME;
        if( configuration != null && configuration.mapName() != null )
        {
            mapName = configuration.mapName().get();
        }
        stringMap = hazelcastInstance.getMap( mapName );
    }

    @Override
    public void passivateService()
        throws Exception
    {
        stringMap = null;
        hazelcastInstance.getLifecycleService().shutdown();
    }

    @Override
    public HazelcastInstance hazelcastInstanceUsed()
    {
        return hazelcastInstance;
    }

    @Override
    public IMap hazelcastMapUsed()
    {
        return stringMap;
    }

    @Override
    public Reader get( EntityReference ref )
        throws EntityStoreException
    {
        final String serializedState = stringMap.get( ref.identity() );
        if( serializedState == null )
        {
            throw new EntityNotFoundException( ref );
        }
        return new StringReader( serializedState );
    }

    @Override
    public void applyChanges( MapChanges changes )
        throws IOException
    {
        changes.visitMap( new MapChanger()
        {

            @Override
            public Writer newEntity( final EntityReference ref, EntityDescriptor entityDescriptor )
                throws IOException
            {
                return new StringWriter( 1000 )
                {

                    @Override
                    public void close()
                        throws IOException
                    {
                        super.close();
                        stringMap.put( ref.identity(), toString() );
                    }
                };
            }

            @Override
            public Writer updateEntity( EntityReference ref, EntityDescriptor entityDescriptor )
                throws IOException
            {
                return newEntity( ref, entityDescriptor );
            }

            @Override
            public void removeEntity( EntityReference ref, EntityDescriptor entityDescriptor )
                throws EntityNotFoundException
            {
                stringMap.remove( ref.identity() );
            }
        } );
    }

    @Override
    public Input<Reader, IOException> entityStates()
    {
        return new Input<Reader, IOException>()
        {
            @Override
            public <ReceiverThrowableType extends Throwable> void transferTo( Output<? super Reader, ReceiverThrowableType> output )
                throws IOException, ReceiverThrowableType
            {
                output.receiveFrom( new Sender<Reader, IOException>()
                {
                    @Override
                    public <ReceiverThrowableType extends Throwable> void sendTo( Receiver<? super Reader, ReceiverThrowableType> receiver )
                        throws ReceiverThrowableType, IOException
                    {
                        for( Map.Entry<String, String> eachEntry : stringMap.entrySet() )
                        {
                            receiver.receive( new StringReader( eachEntry.getValue() ) );
                        }
                    }
                } );
            }
        };
    }

    private Config createConfig( HazelcastConfiguration configuration )
        throws IOException
    {
        String hzConfLocation = configuration.configXmlLocation().get();
        if( hzConfLocation == null || hzConfLocation.isEmpty() )
        {
            hzConfLocation = "hazelcast-default.xml";
        }
        Config conf;
        if( hzConfLocation.contains( ":" ) )
        {
            conf = new UrlXmlConfig( hzConfLocation );
        }
        else
        {
            conf = new ClasspathXmlConfig( hzConfLocation );
        }
        return conf;
    }
}


text:
import getpass
import sys
import shelve
import time
import logging
import os
from urlparse import urljoin

import json
import requests

import Tkinter as tk
import tkFileDialog as tfile

from watchdog.observers import Observer
from watchdog.events import LoggingEventHandler

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from library import Library, get_or_create
from importer import Importer
from uploader import Uploader
from settings import *

# TODO: Figure out how to create database first time and migrations
engine = create_engine('sqlite:///tinsparrow.db', echo=False)

class TinWatch(object):
    def __init__(self):
        # TODO: Convert to PySide GUI Application
        # Currently using tkinter because it's easy
        self.session = self.create_db_session()

    def create_db_session(self):
        Session = sessionmaker()
        Session.configure(bind=engine)
        return Session()

    def main(self):
        root = tk.Tk()
        app = LoginWindow(root)
        root.mainloop()
        #
        # library = session.query(Library).filter_by(path=LIBRARY_PATH).first()
        # if not library:
        #     library = Library()
        #     library.path = LIBRARY_PATH
        #     session.add(library)
        #
        # session.commit()
        #
        # importer = Importer()
        # importer.find_media(session, library)
        #
        # session.commit()
        #
        # uploader = Uploader(token)
        # uploader.sync(session)
        #
        # session.commit()

        # logging.basicConfig(level=logging.INFO,
        #                     format='%(asctime)s - %(message)s',
        #                     datefmt='%Y-%m-%d $H:%M:%S')
        # path = sys.argv[1] if len(sys.argv) > 1 else '.'
        # event_handler = LoggingEventHandler()
        # observer = Observer()
        # observer.schedule(event_handler, path, recursive=True)
        # observer.start()
        # try:
        #     while True:
        #         time.sleep(1)
        # except KeyboardInterrupt:
        #     observer.stop()
        # observer.join()

class SettingsWindow(tk.Tk):
    def __init__(self, root):
        root.title('Settings')
        root.geometry('600x320')
        frame = tk.Frame(root, padx=10, pady=10)
        frame.pack(fill=tk.BOTH, expand=True)
        self.root = root
        self.parent = frame
        self.initialize()

    def initialize(self):
        self.file_label = tk.Label(self.parent, text="Set a directory to scan.")
        self.file_label.pack()
        self.file_button = tk.Button(self.parent, text="Add Music", command=self.ask)
        self.file_button.pack()
        self.listbox = tk.Listbox(self.parent)
        self.listbox.pack()
        self.save_button = tk.Button(self.parent, text="Save", command=self.save)
        self.save_button.pack()
        self.refresh_listbox()

    def ask(self):
        music_path = tfile.askdirectory(parent=self.parent)
        self.add_music_directory(music_path)

    def add_music_directory(self, music_path=None):
        if not os.path.isdir(music_path):
            return
        library = get_or_create(self.session, Library, path=music_path)
        self.session.commit()
        self.refresh_listbox()

    def refresh_listbox(self):
        self.listbox.delete(0, tk.END)
        self.libraries = tw.session.query(Library).all()
        for library in self.libraries:
            self.listbox.insert(tk.END, library.path)

    def save(self):
        self.parent.destroy()
        MonitorWindow(self.root)

class MonitorWindow(tk.Tk):
    def __init__(self, root):
        root.title('Monitor')
        root.geometry('600x320')
        frame = tk.Frame(root, padx=10, pady=10)
        frame.pack(fill=tk.BOTH, expand=True)
        self.root = root
        self.parent = frame
        self.initialize()

    def initialize(self):
        self.settings_button = tk.Button(self.parent, text="Settings", command=self.open_settings)
        self.settings_button.pack()

    def open_settings(self):
        self.parent.destroy()
        SettingsWindow(self.root)

class LoginWindow(tk.Tk):
    def __init__(self, root):
        root.title('Login')
        root.geometry('300x160')
        frame = tk.Frame(root, padx=10, pady=10)
        frame.pack(fill=tk.BOTH, expand=True)
        self.parent = frame
        self.root = root
        self.user_string = tk.StringVar()
        self.password_string = tk.StringVar()
        self.app_config = shelve.open(CONFIG)
        self.initialize()

    def initialize(self):
        if self.check_token(self.app_config.get('token', False)):
            self.open_monitor()
        else:
            self.user_label = tk.Label(self.parent, text="Username: ")
            self.user_label.pack()
            self.user_entry = tk.Entry(self.parent, textvariable=self.user_string)
            self.user_entry.pack()
            self.password_label = tk.Label(self.parent, text="Password: ")
            self.password_label.pack()
            self.password_entry = tk.Entry(self.parent, show="*", textvariable=self.password_string)
            self.password_entry.pack()
            self.login_button = tk.Button(self.parent, borderwidth=4, text="Login", width=10, pady=8, command=self.act)
            self.login_button.pack(side=tk.BOTTOM)
            self.password_entry.bind('<Return>', self.enter)
            self.user_entry.focus_set()

    def act(self):
        token = self.authenticate(self.user_string.get(), self.password_string.get())
        if token:
            self.app_config['token'] = token
            self.open_settings()
        else:
            self.root.title('Login Failure: Try again...')

    def open_settings(self):
        self.app_config.close()
        self.parent.destroy()
        SettingsWindow(self.root)

    def open_monitor(self):
        self.app_config.close()
        self.parent.destroy()
        MonitorWindow(self.root)

    def enter(self, event):
            self.act()

    def authenticate(self, username, password):
        url = urljoin(API_URL, 'token-auth/')
        auth_r = requests.post(url, data={'username': username, 'password': password})
        if auth_r.status_code == 200:
            token_json = json.loads(auth_r.content)
            token = token_json.get('token', None)
            if token:
                return token
        else:
            return False

    def check_token(self, token):
        # TODO: This can be used to check internet connectivity?
        url = API_URL
        headers = {'Authorization': 'Token {}'.format(token)}
        auth_r = requests.get(url, data={}, headers=headers)
        if auth_r.status_code == 200:
            return True
        else:
            return False

if __name__ == "__main__":
    tw = TinWatch()
    tw.main()


text:
class IO
  def self.binread(file, *arg)
    unless arg.size < 3
      raise ArgumentError, "wrong number of arguments (#{1+arg.size} for 1..3)"
    end

    File.open(file,"rb") do |f|
      f.read(*arg)
    end
  end

  def self.read(name, length_or_options=undefined, offset=0, options=nil)
    name = Rubinius::Type.coerce_to_path name
    mode = "r"

    if length_or_options.equal? undefined
      length = undefined
    elsif Rubinius::Type.object_kind_of? length_or_options, Hash
      length = undefined
      offset = 0
      options = length_or_options
    elsif length_or_options
      offset = Rubinius::Type.coerce_to(offset || 0, Fixnum, :to_int)
      raise Errno::EINVAL, "offset must not be negative" if offset < 0

      length = Rubinius::Type.coerce_to(length_or_options, Fixnum, :to_int)
      raise ArgumentError, "length must not be negative" if length < 0
    else
      length = undefined
    end

    if options
      mode = options[:mode] || "r"
    end

    # Detect pipe mode
    if name[0] == ?|
      io = IO.popen(name[1..-1], "r")
      return nil unless io # child process
    else
      io = File.new(name, mode)
    end

    str = nil
    begin
      io.seek(offset) unless offset == 0

      if length.equal?(undefined)
        str = io.read
      else
        str = io.read length
      end
    ensure
      io.close
    end

    return str
  end

  def self.try_convert(obj)
    Rubinius::Type.try_convert obj, IO, :to_io
  end

  class StreamCopier
    def initialize(from, to, length, offset)
      @length = length
      @offset = offset

      @from_io, @from = to_io(from, "rb")
      @to_io, @to = to_io(to, "wb")

      @method = read_method @from
    end

    def to_io(obj, mode)
      if obj.kind_of? IO
        flag = true
        io = obj
      else
        flag = false

        if obj.kind_of? String
          io = File.open obj, mode
        elsif obj.respond_to? :to_path
          path = Rubinius::Type.coerce_to obj, String, :to_path
          io = File.open path, mode
        else
          io = obj
        end
      end

      return flag, io
    end

    def read_method(obj)
      if obj.respond_to? :readpartial
        :readpartial
      else
        :read
      end
    end

    def run
      @from.ensure_open_and_readable
      @to.ensure_open_and_writable

      saved_pos = @from.pos if @from_io

      @from.seek @offset, IO::SEEK_CUR if @offset

      size = rest = @length ? @length : 16384
      bytes = 0

      begin
        while data = @from.send(@method, size, "")
          @to.write data
          bytes += data.size
          rest -= data.size

          break unless rest > 0
        end
      rescue EOFError
        # done reading
      end

      @to.flush
      return bytes
    ensure
      if @from_io
        @from.pos = saved_pos if @offset
      else
        @from.close
      end

      @to.close unless @to_io
    end
  end

  def self.copy_stream(from, to, max_length=nil, offset=nil)
    StreamCopier.new(from, to, max_length, offset).run
  end

  # Argument matrix for IO#gets and IO#each:
  #
  #  separator / limit | nil | >= 0 | < 0
  # ===================+=====+======+=====
  #  String (nonempty) |  A  |  B   |  C
  #                    +-----+------+-----
  #  ""                |  D  |  E   |  F
  #                    +-----+------+-----
  #  nil               |  G  |  H   |  I
  #

  class EachReader
    def initialize(io, buffer, separator, limit)
      @io = io
      @buffer = buffer
      @separator = separator
      @limit = limit
      @skip = nil
    end

    def each(&block)
      if @separator
        if @separator.empty?
          @separator = "\n\n"
          @skip = 10
        end

        if @limit
          read_to_separator_with_limit(&block)
        else
          read_to_separator(&block)
        end
      else
        if @limit
          read_to_limit(&block)
        else
          read_all(&block)
        end
      end
    end

    # method A, D
    def read_to_separator
      str = ""

      until @buffer.exhausted?
        available = @buffer.fill_from @io, @skip
        break unless available > 0

        if count = @buffer.find(@separator)
          str << @buffer.shift(count)

          str.taint
          $. = @io.increment_lineno
          @buffer.discard @skip if @skip

          yield str

          str = ""
        else
          str << @buffer.shift
        end
      end

      str << @buffer.shift
      unless str.empty?
        str.taint
        $. = @io.increment_lineno
        yield str
      end
    end

    # method B, E
    def read_to_separator_with_limit
      str = ""

      #TODO: implement ignoring encoding with negative limit
      wanted = limit = @limit.abs

      until @buffer.exhausted?
        available = @buffer.fill_from @io, @skip
        break unless available > 0

        if count = @buffer.find(@separator)
          bytes = count < wanted ? count : wanted
          str << @buffer.shift(bytes)

          str.taint
          $. = @io.increment_lineno
          @buffer.discard @skip if @skip

          yield str

          str = ""
          wanted = limit
        else
          if wanted < available
            str << @buffer.shift(wanted)

            str.taint
            $. = @io.increment_lineno
            @buffer.discard @skip if @skip

            yield str

            str = ""
            wanted = limit
          else
            str << @buffer.shift
            wanted -= available
          end
        end
      end

      str << @buffer.shift
      unless str.empty?
        str.taint
        $. = @io.increment_lineno
        yield str
      end
    end

    # Method G
    def read_all
      str = ""
      until @buffer.exhausted?
        @buffer.fill_from @io
        str << @buffer.shift
      end

      unless str.empty?
        str.taint
        $. = @io.increment_lineno
        yield str
      end
    end

    # Method H
    def read_to_limit
      str = ""
      wanted = limit = @limit.abs

      until @buffer.exhausted?
        available = @buffer.fill_from @io
        if wanted < available
          str << @buffer.shift(wanted)

          str.taint
          $. = @io.increment_lineno
          yield str

          str = ""
          wanted = limit
        else
          str << @buffer.shift
          wanted -= evailable
        end
      end
    end
  end

  def increment_lineno
    @lineno += 1
  end

  def each(sep_or_limit=$/, limit=nil, &block)
    return to_enum(:each, sep_or_limit, limit) unless block_given?

    ensure_open_and_readable

    if limit
      limit = Rubinius::Type.coerce_to limit, Integer, :to_int
      sep = sep_or_limit ? StringValue(sep_or_limit) : nil
    else
      case sep_or_limit
      when String
        sep = sep_or_limit
      when nil
        sep = nil
      else
        unless sep = Rubinius::Type.check_convert_type(sep_or_limit, String, :to_str)
          sep = $/
          limit = Rubinius::Type.coerce_to sep_or_limit, Integer, :to_int
        end
      end
    end

    return if @ibuffer.exhausted?

    EachReader.new(self, @ibuffer, sep, limit).each(&block)

    self
  end

  alias_method :each_line, :each

  def gets(sep_or_limit=$/, limit=nil)
    each sep_or_limit, limit do |line|
      $_ = line if line
      return line
    end

    nil
  end
end


text:
/**
 * @file   edclient.c
 * @author Jiangwen Su <uukuguy@gmail.com>
 * @date   2014-11-08 03:48:12
 *
 * @brief
 *
 *
 */

#include <czmq.h>
#include "common.h"
#include "logger.h"
#include "filesystem.h"
#include "everdata.h"

#include "zpipe.h"

static char *file_data = NULL;
static uint32_t file_size = 0;

/* -------- struct client_t -------- */
typedef struct client_t {
    ZPIPE_ACTOR;

    const char *endpoint;
    int id;
    const char *file_data;
    uint32_t file_size;
    uint32_t total_files;
    int op_code;
    const char *key;
    const char *filename;
    int verbose;

    uint32_t start_index;
    /*zactor_t *actor;*/

} client_t;

/* ================ prepare_file_data() ================ */
int prepare_file_data(const char *filename)
{
    FILE *file = fopen(filename, "rb");
    if ( file == NULL ){
        error_log("fopen() failed. file:%s", filename);
        return -1;
    }

    fseek(file, 0, SEEK_END);
    uint32_t size = ftell(file);
    fseek(file, 0, SEEK_SET);

    char *buf = (char*)zmalloc(size);

    memset(buf, 0, sizeof(size));
    uint32_t readed = fread(buf, 1, size, file);
    if ( readed != size ){
        error_log("fread() failed. readed:%d file_size:%d", readed, size);
        fclose(file);
        return -1;
    }

    fclose(file);

    file_data = buf;
    file_size = size;

    return 0;
}

/* ================ client_rebuild_data_key() ================ */
void client_rebuild_data_key(client_t *client, uint32_t data_id, char *key)
{
    char file_name[NAME_MAX];
    get_path_file_name(client->filename, file_name, NAME_MAX - 1);

    sprintf(key, "/test/%s/%04d/%08d-%s", client->key, client->id, client->start_index + data_id, file_name);
}

/* ================ delete_data() ================ */
int delete_data(zsock_t *sock, const char *key)
{
    /* ---------------- Send Message ---------------- */
    zmsg_t *delete_msg = create_action_message(MSG_ACTION_DEL);
    message_add_key_data(delete_msg, key, "", 0);

    zmsg_send(&delete_msg, sock);

    /* ---------------- Receive Message ---------------- */

    zmsg_t *recv_msg = zmsg_recv(sock);
    if ( recv_msg == NULL ){
        return -2;
    }
    zmsg_print(recv_msg);

    int rc = -1;
    if (message_check_status(recv_msg, MSG_STATUS_WORKER_NOTFOUND) == 0 ){
        warning_log("Not Found. key=%s", key);
        rc = 0;
    } else if ( message_check_status(recv_msg, MSG_STATUS_WORKER_ERROR) == 0 ){
        error_log("Return MSG_STATUS_WORKER_ERROR. key=%s", key);
        rc = -1;
    }

    zmsg_destroy(&recv_msg);

    return rc;
}

/* ================ download_data() ================ */
int download_data(zsock_t *sock, const char *key)
{
    /* ---------------- Send Message ---------------- */
    zmsg_t *download_msg = create_action_message(MSG_ACTION_GET);
    message_add_key_data(download_msg, key, "", 0);

    zmsg_send(&download_msg, sock);

    /* ---------------- Receive Message ---------------- */

    zmsg_t *recv_msg = zmsg_recv(sock);
    if ( recv_msg == NULL ){
        return -2;
    }
    /*zmsg_print(recv_msg);*/

    int rc = -1;
    if (message_check_status(recv_msg, MSG_STATUS_WORKER_NOTFOUND) == 0 ){
        warning_log("Not Found. key=%s", key);
        rc = 0;
    } else if ( message_check_status(recv_msg, MSG_STATUS_WORKER_ERROR) == 0 ){
        error_log("Return MSG_STATUS_WORKER_ERROR. key=%s", key);
        rc = -1;
    } else {
        /*zmsg_print(recv_msg);*/
        zframe_t *frame_msgtype = zmsg_first(recv_msg);
        if ( frame_msgtype != NULL ){
            int16_t msgtype = *(int16_t*)zframe_data(frame_msgtype);
            if ( msgtype == MSGTYPE_DATA ){
                zmsg_first(recv_msg);

                zframe_t *frame_key = zmsg_next(recv_msg);
                UNUSED const char *key = (const char *)zframe_data(frame_key);

                zframe_t *frame_data = zmsg_next(recv_msg);
                UNUSED const char *data =  (const char *)zframe_data(frame_data);
                UNUSED uint32_t data_size = zframe_size(frame_data);
                /*notice_log("Receive key:%s data_size:%d", key, data_size);*/
                rc = 0;
            }
        }
    }

    zmsg_destroy(&recv_msg);

    return rc;
}

/* ================ upload_data() ================ */
int upload_data(zsock_t *sock, const char *key, const char *data, uint32_t data_size)
{
    /* ---------------- Send Message ---------------- */
    zmsg_t *upload_msg = create_action_message(MSG_ACTION_PUT);
    message_add_key_data(upload_msg, key, data, data_size);

    zmsg_send(&upload_msg, sock);

    /* ---------------- Receive Message ---------------- */

    zmsg_t *recv_msg = zmsg_recv(sock);
    if ( recv_msg == NULL ){
        return -2;
    }
    /*zmsg_print(recv_msg);*/

    int rc = 0;
    if (message_check_status(recv_msg, MSG_STATUS_WORKER_ACK) == 0 ){
        /*info_log("Return MSG_STATUS_WORKER_ACK. key=%s", key);*/
        rc = 0;
    } else if ( message_check_status(recv_msg, MSG_STATUS_WORKER_ERROR) == 0 ){
        error_log("Return MSG_STATUS_WORKER_ERROR. key=%s", key);
        rc = -1;
    }

    zmsg_destroy(&recv_msg);

    return rc;
}

#define RETRIES 3
/* ================ client_thread_main() ================ */
void client_thread_main(zsock_t *pipe, void *user_data)
{
    client_t *client = (client_t*)user_data;
    int id = client->id;
    UNUSED const char *file_data = client->file_data;
    UNUSED uint32_t file_size = client->file_size;

    trace_log("Client %d Ready.", id);

    /*ZPIPE_ACTOR_THREAD_BEGIN(pipe);*/

    zsock_t *sock_client = zsock_new_req(client->endpoint);
    if ( sock_client == NULL ){
        error_log("Connect broker failed. Client %d", client->id);
        return;
    }

    uint32_t file_count = 0;
    while ( true ){

        char key[NAME_MAX];
        client_rebuild_data_key(client, file_count, key);

        int retries = 0;
        while ( retries++ < RETRIES ) {

            int rc = 0;
            if ( client->op_code == 1 ) {
                rc = upload_data(sock_client, key, file_data, file_size);
            } else if ( client->op_code == 2 ) {
                rc = download_data(sock_client, key);
            } else if ( client->op_code == 3 ) {
                rc = delete_data(sock_client, key);
            }
            if ( rc == -2 ) break;
            if ( rc == 0 ) break;

            notice_log("Retry %d/%d...", retries, RETRIES);
            zclock_sleep(1000);
        }

        /* ---------------- Check exit loop ---------------- */

        file_count++;
        if ( file_count % 100 == 1 || file_count + 5 >= client->total_files ){
            info_log("Client %d Send message %d/%d", client->id, file_count, client->total_files);
        }
        if ( file_count >= client->total_files )
            break;
    }

    /*ZPIPE_ACTOR_THREAD_END(pipe);*/

    zsock_destroy(&sock_client);

    trace_log("Client %d Exit.", id);

}

/* ================ client_new() ================ */
client_t *client_new(int client_id, const char *endpoint, int op_code, uint32_t total_files, const char *key, const char *filename, int verbose)
{
    client_t *client = (client_t*)malloc(sizeof(client_t));
    memset(client, 0, sizeof(client_t));

    client->id = client_id;
    client->endpoint = endpoint;
    client->op_code = op_code;
    client->total_files = total_files;
    client->key = key;
    client->filename = filename;
    client->verbose = verbose;

    client->file_data = file_data;
    client->file_size = file_size;

    ZPIPE_ACTOR_NEW(client, client_thread_main);

    return client;
}

/* ================ client_free() ================ */
void client_free(client_t *client)
{
    ZPIPE_ACTOR_FREE(client);
    free(client);
}

/* -------- struct edclient_t -------- */
typedef struct edclient_t {
    ZPIPE;

    const char *endpoint;
    int op_code;
    uint32_t total_clients;
    uint32_t total_files;
    const char *key;
    const char *filename;
    int verbose;
} edclient_t;

/* ================ edclient_new() ================ */
edclient_t *edclient_new(const char *endpoint, int op_code, uint32_t total_clients, uint32_t total_files, const char *key, const char *filename, int verbose)
{
    edclient_t *edclient = (edclient_t*)malloc(sizeof(edclient_t));
    memset(edclient, 0, sizeof(edclient_t));

    edclient->endpoint = endpoint;
    edclient->op_code = op_code;
    edclient->total_clients = total_clients;
    edclient->total_files = total_files;
    edclient->key = key;
    edclient->filename = filename;
    edclient->verbose = verbose;

    return edclient;
}

/* ================ edclient_free() ================ */
void edclient_free(edclient_t *edclient)
{
    ZPIPE_FREE(edclient, client_free, client_t);

    free(edclient);
}

/* ================ edclient_loop() ================ */
void edclient_loop(edclient_t *edclient){

    ZPIPE_NEW_BEGIN(edclient, edclient->total_clients);

    client_t *client = client_new(i,
            edclient->endpoint,
            edclient->op_code,
            edclient->total_files,
            edclient->key,
            edclient->filename,
            edclient->verbose);

    ZPIPE_NEW_END(edclient, client);

    ZPIPE_LOOP(edclient);
}

/* ================ run_edclient() ================ */
int run_edclient(const char *endpoint, int op_code, uint32_t total_clients, uint32_t total_files, const char *key, const char *filename, int verbose)
{
    prepare_file_data(filename);

    edclient_t *edclient = edclient_new(endpoint, op_code, total_clients, total_files, key, filename, verbose);

    edclient_loop(edclient);

    edclient_free(edclient);

    return 0;
}


text:
includeCore('libs/jquery-latest');

includeCore('springbok.base');
includeCore('springbok.breadcrumbs');
includeCore('springbok.ajax');
includeCore('ui/THtml');

includePlugin('users/_users');

define('AJAX_CONTENT_EFFECT',false);