Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

FunctionContext does not contain a cache. That means any function that you execute with onMember must contain code like this:

Code Block

public void execute(FunctionContext context) {
    Cache cache = CacheFactory.getAnyInstance();
//...do work with the cache
}

...

  • It's not clear that ctx.getDataSet does not return the local data.
  • The local data set is not mockable for unit tests, because this static function call extracts it using internal APIs on concrete classes. This also prevents this sort of function from being tested in a pure unit test.
  • The user has to know that PartitionRegionHelper exists; the API is not obvious
  • The various methods on PartitionRegionHelper are confusing, specifically it's unclear to a user why they should use getLocalDataFOrContext instead of getLocalData

 

 

 

No way to get a spring data repository of the local data set of a function

This is not specifically an issue in the geode codebase, but it affects a lot of geode users.

Spring Gemfire provides an simplified function API. Spring Data Gemfire allows the user to generate a repository object to access a region. However, there is no way to generate a repository that accesses the local data for the function.

 

Here's an example

Code Block
public interface PostRepository extends GemfireRepository<Post, PostId> {
  @Query("select * from /posts where id.person=$1")
  public Collection<Post> findPosts(String personName);
}  

public class Functions {
  
  //This repository accesses the entire data for the region on all members.
  @Autowired
  PostRepository postRepository;
  
  @GemfireFunction(HA=true)
  public SentimentResult getSentimentDoesntWork(Region<PostId, Post> localPosts, 
      @Filter Set<String> personNames) throws Exception {
    String personName = personNames.iterator().next();
    
    //This works, because localPosts is bound to the local data for the region    
    Collection<Post> posts = localPosts.query("id.person='" + personName + "'");

    //But I really want to use spring data repositories. Unfortunately, 
    //I can't get a repository here
    PostRepository localDataRepository == ??
    Collection<Post> posts  = localDataRepository.findPosts(personName);
    
  }

 

FunctionService.onMembers relies on a singleton DistributedSystem

 

FunctionService.onMembers doesn't take a Cache or DistributedSystem. This locks us in to having a singleton DistributedSystem, because FunctionService will always look up the singleton.

Having a static FunctionService.onXXX means users can't mock the functionService

 

To invoke a function, the user code needs to refer to the static FunctionService.onXXX methods ( see below). That means that code that contains these static calls can't be tested with a test that mocks the function service.

Code Block
FunctionService.onRegion(region)
        .withArgs(context)
        .withCollector(collector)
        .execute(LuceneFunction.ID);

It might be better to have a cache.getFunctionService

 

Functions are not easy to implement for the common case of having one result

The function context has a ResultSender with methods like sendResult, lastResult, sendException, etc.

However, the common case is that the user wants to send a single result, so we should provide a simpler function interface for this case that has a single return value.

 

Lambdas and functions

Lambdas cannot be used for Geode functions, because there are multiple non abstract methods on function like hasResult, isHA, etc.