devigned / profile-playground

2 stars 1 forks source link

Provide Generic Http Apis for additional flexibility #14

Open markcowl opened 7 years ago

markcowl commented 7 years ago

Provide APIs in AzureClient that can perform HTTP operations (GET, PUT, POST, DELETE, HEAD, PATCH, etc.) with LRO support using generic types (dynamic, disctionary, or otherwise json serializable types). This would allow both using less structured types for those who did not need type safety, and making calls to RPs that do not have SDKs (very old or very new API Versions).

anuchandy commented 7 years ago

Wanted to highlight the need for externalizing the LRO polling state.

Today the generated sync and async methods that internally uses AzureClient LRO implementation returns only after the operation is terminated i.e. polling, async waiting everything is hidden from the user.

Think of a scenario where end user initiated the LRO operation, with following consraints:

  1. Don't want to wait (sync/async wait) for the operation to finish in the current thread
  2. Don't want to spin another thread/task just to wait
  3. He may be terminating the main process.
  4. He wanted to resume LRO polling later (from a different thread or process)

In order to support this the LRO state needs to be externalized.

An example of an environment where this would be useful is service fabric nodes, these are state-less nodes with instance of same application deployed. These type of application will be designed by considering the state-less nature of the enviorment it runs, if they want to take dependency on our sdks/runtime then that also needs to be stateless.

anuchandy commented 7 years ago

Below sample code shows one way of doing this using Rx.

The idea is the BeginAsync call returns immediately just like today but instead of returning the response of the request, it returns a monitor object that user can use to poll, get the current polling state which is serializable The monitor can be also created from the polling state and continue polling.

// Gets a monitor observable representing LRO VM Delete action
//
Observable<DeleteOperationMonitor> monitorObservable = virtualMachine.beginDeleteAsync();

// Initiate action, this will fire delete request and return immediately with the initial response
//
DeleteOperationMonitor monitor = monitorObservable.toBlocking().last();

// Gets the progress tracking observable from monitor
//
Observable<DeletePollingState> pollingObservable = monitor.toObservable();

// Do polling 3 times and get result of last poll
//
DeletePollingState savedState = pollingObservable.take(2).toBlocking().last();

//Save the state to file or db savedState
//
File file = File.write(savedState);

//
// Creates monitor object from the saved state
//
DeletePollingState savedState = file.read<DeletePollingState>();

monitorObservable = DeleteOperationMonitor.fromPollingState(computeManager.inner().restClient(), savedState);

// Gets the monitor
//
monitor = monitorObservable.toBlocking().last();

// Synchronously wait for delete to complete or fail
//
monitor.toObservable().toBlocking().last();